Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


meshchatx/src/backend/rrc/manager.py 32e97c105419d3bcede5c1311df3ffb63b8305a4 (32e97c10) Text, 69.07 KB

T8b949e# SPDX-License-Identifier: 0BSD

T8b949e"""Reticulum Relay Chat session management.

Contains RRCHub, which owns the Reticulum link and protocol state for a
single hub, and RRCManager, which tracks the set of configured hubs,
persists them, and relays change and message notifications to the application.
"""

Tff7b72import T7ee787contextlib
Tff7b72import T7ee787hashlib
Tff7b72import T7ee787os
Tff7b72import T7ee787re
Tff7b72import T7ee787threading
Tff7b72import T7ee787time
Tff7b72from T7ee787collections Tff7b72import Te6edf3deque

Tff7b72import T7ee787RNS

Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rrc Tff7b72import Te6edf3protocol Tff7b72as Te6edf3proto
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rrcT7ee787.T7ee787room_key_crypto Tff7b72import Te6edf3decrypt_room_keyTb4b4b4, Te6edf3encrypt_room_key
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787rrcT7ee787.T7ee787server Tff7b72import Te6edf3_LoopbackEndpoint

Te6edf3DEFAULT_DEST_NAME Tff7b72= Te6edf3protoTff7b72.Td2a8ffDEFAULT_DEST_NAME
Te6edf3BAD_KEY_MARKERS Tff7b72= Tb4b4b4(Ta5d6ff"Ta5d6ffbad key (+k)Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffbad keyTa5d6ff"Tb4b4b4)
Te6edf3FORCED_LEAVE_MARKERS Tff7b72= Tb4b4b4(Ta5d6ff"Ta5d6ffkicked fromTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffbanned fromTa5d6ff"Tb4b4b4)

Te6edf3HISTORY_DIR_NAME Tff7b72= Ta5d6ff"Ta5d6ffrrc_historyTa5d6ff"
Te6edf3HISTORY_FILENAME_SANITIZE_RE Tff7b72= Te6edf3reTff7b72.Td2a8ffcompileTb4b4b4(Ta5d6ffrTa5d6ff"Ta5d6ff[^a-z0-9._-]+Ta5d6ff"Tb4b4b4)

Te6edf3H_KIND Tff7b72= Ta5d6ff"Ta5d6ffkTa5d6ff"
Te6edf3H_SRC Tff7b72= Ta5d6ff"Ta5d6ffsTa5d6ff"
Te6edf3H_NICK Tff7b72= Ta5d6ff"Ta5d6ffnTa5d6ff"
Te6edf3H_TEXT Tff7b72= Ta5d6ff"Ta5d6fftTa5d6ff"
Te6edf3H_TS Tff7b72= Ta5d6ff"Ta5d6fftsTa5d6ff"
Te6edf3H_MENTION Tff7b72= Ta5d6ff"Ta5d6ffmTa5d6ff"


Tff7b72class T56d364RRCHubTb4b4b4:
T8b949e"""A single RRC hub connection and its associated rooms and history."""

Te6edf3STATUS_DISCONNECTED Tff7b72= T79c0ff0
Te6edf3STATUS_CONNECTING Tff7b72= T79c0ff1
Te6edf3STATUS_CONNECTED Tff7b72= T79c0ff2
Te6edf3STATUS_FAILED Tff7b72= T79c0ff3

Te6edf3CLEAN_HISTORY_INTERVAL Tff7b72= T79c0ff5
Te6edf3SYS_NOTICE_TIMEOUT Tff7b72= T79c0ff600

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3managerTb4b4b4, Te6edf3hub_hashTb4b4b4, Te6edf3dest_nameTff7b72=Tff7b72NoneTb4b4b4, Te6edf3nameTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmanager Tff7b72= Te6edf3manager
Tff7b72selfTff7b72.Td2a8ffhub_hash Tff7b72= Te6edf3hub_hash
Tff7b72selfTff7b72.Td2a8ffdest_name Tff7b72= Te6edf3dest_name Tff7b72or Te6edf3protoTff7b72.Td2a8ffDEFAULT_DEST_NAME
Tff7b72selfTff7b72.Td2a8ffname Tff7b72= Te6edf3name Tff7b72or Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3hub_hashTb4b4b4)

Tff7b72selfTff7b72.Td2a8fflink Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_DISCONNECTED
Tff7b72selfTff7b72.Td2a8ffstatus_text Tff7b72= Ta5d6ff"Ta5d6ffDisconnectedTa5d6ff"
Tff7b72selfTff7b72.Td2a8ffwelcomed Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffhub_name Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffhub_version Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffhub_caps Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffmotd Tff7b72= Tff7b72None

Tff7b72selfTff7b72.Td2a8ffmax_nick_bytes Tff7b72= Te6edf3protoTff7b72.Td2a8ffDEFAULT_MAX_NICK_BYTES
Tff7b72selfTff7b72.Td2a8ffmax_room_name_bytes Tff7b72= Te6edf3protoTff7b72.Td2a8ffDEFAULT_MAX_ROOM_BYTES
Tff7b72selfTff7b72.Td2a8ffmax_msg_body_bytes Tff7b72= Te6edf3protoTff7b72.Td2a8ffDEFAULT_MAX_MSG_BYTES
Tff7b72selfTff7b72.Td2a8ffmax_rooms_per_session Tff7b72= Te6edf3protoTff7b72.Td2a8ffDEFAULT_MAX_ROOMS
Tff7b72selfTff7b72.Td2a8ffrate_limit_msgs_per_minute Tff7b72= Te6edf3protoTff7b72.Td2a8ffDEFAULT_RATE_PER_MINUTE

Tff7b72selfTff7b72.Td2a8ffrooms Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessages Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffnotices Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffunread_rooms Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_counts Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffmention_rooms Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmembers Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffnicks Tff7b72= Tb4b4b4{Tb4b4b4}

Tff7b72selfTff7b72.Td2a8ffauto_reconnect Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffcustom_name Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffhub_icon Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffroom_order Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffauto_list Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffauto_who Tff7b72= Tff7b72False

Tff7b72selfTff7b72.Td2a8ff_lock Tff7b72= Te6edf3threadingTff7b72.Td2a8ffRLockTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_resource_expectations Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ff_sent_ids Tff7b72= Te6edf3dequeTb4b4b4(Te6edf3maxlenTff7b72=T79c0ff256Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ff_hello_thread Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_stop_hello Tff7b72= Te6edf3threadingTff7b72.Td2a8ffEventTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_manual_disconnect Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_reconnect_attempts Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_reconnect_timer Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_had_session Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_pending_pings Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ff_last_history_clean Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffclean_last_removed Tff7b72= T79c0ff0

Tff7b72selfTff7b72.Td2a8ffavailable_rooms Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ff_silent_list_pending Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_silent_who_rooms Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffnick_override Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_pending_joins Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_pending_parts Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_silent_joins Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ff_history_write_failed Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_seq_counter Tff7b72= T79c0ff0

Tff7b72def Td2a8ff_next_seqTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_seq_counter Tff7b72+Tff7b72= T79c0ff1
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_seq_counter

Tff7b72def Td2a8ff_logTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3msgTb4b4b4, Te6edf3levelTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3level Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3level Tff7b72= Te6edf3RNSTff7b72.Td2a8ffLOG_INFO
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ff[RRC Ta5d6ff" Tff7b72+ Tff7b72selfTff7b72.Td2a8ffname Tff7b72+ Ta5d6ff"Ta5d6ff] Ta5d6ff" Tff7b72+ Te6edf3msgTb4b4b4, Te6edf3levelTb4b4b4)

Tff7b72def Td2a8ffadd_roomTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Te6edf3room_n Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffroomsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3room_nTb4b4b4)
Tff7b72if Te6edf3room_n Tff7b72not Tff7b72in Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4[Te6edf3room_nTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72return Te6edf3room_n

Tff7b72def Td2a8ffremove_roomTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffroomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffpopTb4b4b4(Te6edf3rTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_countsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3rTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmention_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmembersTff7b72.Td2a8ffpopTb4b4b4(Te6edf3rTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_delete_historyTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffclear_messagesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Te6edf3r Tff7b72in Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4[Te6edf3rTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffunread_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_countsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3rTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmention_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_delete_historyTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffget_membersTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72return Tffa657listTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmembersTff7b72.Td2a8ffgetTb4b4b4(Te6edf3roomTb4b4b4, Tffa657setTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffdisplay_name_forTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3peerTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3peerTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff<unknown>Ta5d6ff"
Te6edf3ph Tff7b72= Tffa657bytesTb4b4b4(Te6edf3peerTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3nick Tff7b72= Tff7b72selfTff7b72.Td2a8ffnicksTff7b72.Td2a8ffgetTb4b4b4(Te6edf3phTb4b4b4)
Tff7b72if Te6edf3nickTb4b4b4:
Tff7b72return Te6edf3nick
Te6edf3resolver Tff7b72= Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffget_name_for_identity_hash
Tff7b72if Te6edf3resolver Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3resolved Tff7b72= Te6edf3resolverTb4b4b4(Te6edf3phTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3resolvedTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3resolvedTb4b4b4:
Tff7b72return Te6edf3resolved
Tff7b72return Te6edf3phTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff12Tb4b4b4]

Tff7b72def Td2a8ffmark_readTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffunread_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_countsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3rTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmention_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffget_display_nameTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Tff7b72selfTff7b72.Td2a8ffcustom_nameTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Tff7b72selfTff7b72.Td2a8ffcustom_nameTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffcustom_nameTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Tff7b72selfTff7b72.Td2a8ffhub_nameTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Tff7b72selfTff7b72.Td2a8ffhub_nameTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffhub_nameTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ffname

Tff7b72def Td2a8ffset_custom_nameTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3nameTb4b4b4, Te6edf3saveTff7b72=Tff7b72TrueTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Te6edf3name Tff7b72is Tff7b72None Tff7b72or Tb4b4b4(Tffa657isinstanceTb4b4b4(Te6edf3nameTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Tff7b72not Te6edf3nameTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffcustom_name Tff7b72= Tff7b72None
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffcustom_name Tff7b72= Tffa657strTb4b4b4(Te6edf3nameTb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3saveTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffget_hub_iconTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Tff7b72selfTff7b72.Td2a8ffhub_iconTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Tff7b72selfTff7b72.Td2a8ffhub_iconTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffhub_iconTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffordered_known_roomsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3known Tff7b72= Tffa657setTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffkeysTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72| Tff7b72selfTff7b72.Td2a8ffrooms
Te6edf3ordered Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3seen Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3room Tff7b72in Tff7b72selfTff7b72.Td2a8ffroom_orderTb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3rn Tff7b72= Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3rn Tff7b72and Te6edf3rn Tff7b72in Te6edf3known Tff7b72and Te6edf3rn Tff7b72not Tff7b72in Te6edf3seenTb4b4b4:
Te6edf3orderedTff7b72.Td2a8ffappendTb4b4b4(Te6edf3rnTb4b4b4)
Te6edf3seenTff7b72.Td2a8ffaddTb4b4b4(Te6edf3rnTb4b4b4)
Tff7b72for Te6edf3room Tff7b72in Tffa657sortedTb4b4b4(Te6edf3known Tff7b72- Te6edf3seenTb4b4b4)Tb4b4b4:
Te6edf3orderedTff7b72.Td2a8ffappendTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72return Te6edf3ordered

Tff7b72def Td2a8ffreorder_roomsTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3room_namesTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3room_namesTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Te6edf3known Tff7b72= Tffa657setTb4b4b4(Tff7b72selfTff7b72.Td2a8ffordered_known_roomsTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3order Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3name Tff7b72in Te6edf3room_namesTb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3nameTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72continue
Tff7b72tryTb4b4b4:
Te6edf3rn Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3nameTb4b4b4)
Tff7b72except Tf85149ValueErrorTb4b4b4:
Tff7b72continue
Tff7b72if Te6edf3rn Tff7b72in Te6edf3known Tff7b72and Te6edf3rn Tff7b72not Tff7b72in Te6edf3orderTb4b4b4:
Te6edf3orderTff7b72.Td2a8ffappendTb4b4b4(Te6edf3rnTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3remaining Tff7b72= Tb4b4b4[Te6edf3r Tff7b72for Te6edf3r Tff7b72in Te6edf3known Tff7b72if Te6edf3r Tff7b72not Tff7b72in Te6edf3orderTb4b4b4]
Tff7b72selfTff7b72.Td2a8ffroom_order Tff7b72= Te6edf3order Tff7b72+ Tffa657sortedTb4b4b4(Te6edf3remainingTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72return Tff7b72True

Tff7b72def Td2a8ffset_hub_iconTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3icon_nameTb4b4b4, Te6edf3saveTff7b72=Tff7b72TrueTb4b4b4)Tb4b4b4:
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787mdi_icon_util Tff7b72import Te6edf3normalize_mdi_icon_name

Te6edf3normalized Tff7b72= Te6edf3normalize_mdi_icon_nameTb4b4b4(Te6edf3icon_nameTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhub_icon Tff7b72= Te6edf3normalized
Tff7b72if Te6edf3saveTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ff_bump_unreadTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3room Tff7b72or Te6edf3room Tff7b72not Tff7b72in Tff7b72selfTff7b72.Td2a8ffroomsTb4b4b4:
Tff7b72return
Tff7b72selfTff7b72.Td2a8ffunread_roomsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_countsTb4b4b4[Te6edf3roomTb4b4b4] Tff7b72= Tffa657minTb4b4b4(T79c0ff9999Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffunread_countsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3roomTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72+ T79c0ff1Tb4b4b4)

Tff7b72def Td2a8ff_set_statusTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3statusTb4b4b4, Te6edf3textTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3status
Tff7b72if Te6edf3text Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstatus_text Tff7b72= Te6edf3text
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffconnectTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72in Tb4b4b4(Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_CONNECTINGTb4b4b4, Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_CONNECTEDTb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72selfTff7b72.Td2a8ff_manual_disconnect Tff7b72= Tff7b72False
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_reconnect_timer Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_reconnect_timerTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_reconnect_timer Tff7b72= Tff7b72None
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_reconnect_attempts Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3text Tff7b72= Ta5d6ff"Ta5d6ffReconnecting (attempt Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_reconnect_attemptsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"
Tff7b72elseTb4b4b4:
Te6edf3text Tff7b72= Ta5d6ff"Ta5d6ffConnectingTa5d6ff"
Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_CONNECTINGTb4b4b4, Te6edf3textTb4b4b4)

Te6edf3t Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ff_connect_workerTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)
Te6edf3tTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_connect_loopbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3serverTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_stop_helloTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Te6edf3link Tff7b72= Te6edf3_LoopbackEndpointTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3serverTb4b4b4)
Te6edf3serverTff7b72.Td2a8ff_attach_loopbackTb4b4b4(Te6edf3linkTb4b4b4, Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflink Tff7b72= Te6edf3link
Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_CONNECTINGTb4b4b4, Ta5d6ff"Ta5d6ffConnected locally, sending HELLOTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_hello_thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ff_hello_loopTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_hello_threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_connect_workerTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3server Tff7b72= Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8fffind_local_serverTb4b4b4(Tff7b72selfTff7b72.Td2a8ffhub_hashTb4b4b4)
Tff7b72if Te6edf3server Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_connect_loopbackTb4b4b4(Te6edf3serverTb4b4b4)
Tff7b72return

Te6edf3timeout_s Tff7b72= T79c0ff20.0
Tff7b72if Tff7b72not Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Tff7b72selfTff7b72.Td2a8ffhub_hashTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffrequest_pathTb4b4b4(Tff7b72selfTff7b72.Td2a8ffhub_hashTb4b4b4)
Te6edf3deadline Tff7b72= Te6edf3timeTff7b72.Td2a8ffmonotonicTb4b4b4(Tb4b4b4) Tff7b72+ Tffa657minTb4b4b4(T79c0ff5.0Tb4b4b4, Te6edf3timeout_sTb4b4b4)
Tff7b72while Te6edf3timeTff7b72.Td2a8ffmonotonicTb4b4b4(Tb4b4b4) Tff7b72< Te6edf3deadlineTb4b4b4:
Tff7b72if Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Tff7b72selfTff7b72.Td2a8ffhub_hashTb4b4b4)Tb4b4b4:
Tff7b72break
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.1Tb4b4b4)

Te6edf3hub_identity Tff7b72= Tff7b72None
Te6edf3deadline Tff7b72= Te6edf3timeTff7b72.Td2a8ffmonotonicTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3timeout_s
Tff7b72while Te6edf3timeTff7b72.Td2a8ffmonotonicTb4b4b4(Tb4b4b4) Tff7b72< Te6edf3deadlineTb4b4b4:
Te6edf3hub_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffrecallTb4b4b4(Tff7b72selfTff7b72.Td2a8ffhub_hashTb4b4b4)
Tff7b72if Te6edf3hub_identity Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72break
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.2Tb4b4b4)

Tff7b72if Te6edf3hub_identity Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_FAILEDTb4b4b4, Ta5d6ff"Ta5d6ffHub identity unknownTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_maybe_schedule_reconnect_after_failed_connectTb4b4b4(Tb4b4b4)
Tff7b72return

Te6edf3app_nameTb4b4b4, Te6edf3aspects Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffapp_and_aspects_from_nameTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffdest_nameTb4b4b4,
Tb4b4b4)
Te6edf3hub_dest Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(
Te6edf3hub_identityTb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffOUTTb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4,
Te6edf3app_nameTb4b4b4,
Tff7b72*Te6edf3aspectsTb4b4b4,
Tb4b4b4)

Tff7b72if Te6edf3hub_destTff7b72.Td2a8ffhash Tff7b72!= Tff7b72selfTff7b72.Td2a8ffhub_hashTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(
Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_FAILEDTb4b4b4,
Ta5d6ff"Ta5d6ffHash/destination name mismatchTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_maybe_schedule_reconnect_after_failed_connectTb4b4b4(Tb4b4b4)
Tff7b72return

Tff7b72selfTff7b72.Td2a8ff_stop_helloTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Te6edf3link Tff7b72= Te6edf3RNSTff7b72.Td2a8ffLinkTb4b4b4(
Te6edf3hub_destTb4b4b4,
Te6edf3established_callbackTff7b72=Tff7b72selfTff7b72.Td2a8ff_on_establishedTb4b4b4,
Te6edf3closed_callbackTff7b72=Tff7b72selfTff7b72.Td2a8ff_on_closedTb4b4b4,
Tb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_packet_callbackTb4b4b4(Tff7b72lambda Te6edf3dataTb4b4b4, Te6edf3pktTb4b4b4: Tff7b72selfTff7b72.Td2a8ff_on_packetTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflink Tff7b72= Te6edf3link
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_FAILEDTb4b4b4, Ta5d6ff"Ta5d6ffConnect error: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_maybe_schedule_reconnect_after_failed_connectTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_maybe_schedule_reconnect_after_failed_connectTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_manual_disconnect Tff7b72or Tff7b72not Tff7b72selfTff7b72.Td2a8ffauto_reconnectTb4b4b4:
Tff7b72return
Tff7b72if Tff7b72selfTff7b72.Td2a8fflink Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return
Tff7b72selfTff7b72.Td2a8ff_schedule_reconnectTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_on_establishedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3linkTff7b72.Td2a8ffset_resource_strategyTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffACCEPT_APPTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_resource_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_resource_advertisedTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_resource_started_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_resource_advertisedTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_resource_concluded_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_resource_concludedTb4b4b4)

Tff7b72tryTb4b4b4:
Te6edf3linkTff7b72.Td2a8ffidentifyTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_logTb4b4b4(Ta5d6ff"Ta5d6ffidentify failed: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72return

Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_CONNECTINGTb4b4b4, Ta5d6ff"Ta5d6ffIdentified, sending HELLOTa5d6ff"Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ff_hello_thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ff_hello_loopTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_hello_threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_hello_loopTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3attempts Tff7b72= T79c0ff0
Tff7b72while Tff7b72not Tff7b72selfTff7b72.Td2a8ff_stop_helloTff7b72.Td2a8ffis_setTb4b4b4(Tb4b4b4) Tff7b72and Tff7b72not Tff7b72selfTff7b72.Td2a8ffwelcomed Tff7b72and Te6edf3attempts Tff7b72< T79c0ff5Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3cur_link Tff7b72= Tff7b72selfTff7b72.Td2a8fflink
Tff7b72if Te6edf3cur_link Tff7b72is Tff7b72None Tff7b72or Te6edf3cur_linkTff7b72.Td2a8ffstatus Tff7b72!= Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffACTIVETb4b4b4:
Tff7b72return
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_send_helloTb4b4b4(Te6edf3cur_linkTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_logTb4b4b4(Ta5d6ff"Ta5d6ffHELLO send failed: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3attempts Tff7b72+Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ff_stop_helloTff7b72.Td2a8ffwaitTb4b4b4(Te6edf3timeoutTff7b72=T79c0ff3.0Tb4b4b4)
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffwelcomed Tff7b72and Tff7b72not Tff7b72selfTff7b72.Td2a8ff_stop_helloTff7b72.Td2a8ffis_setTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_FAILEDTb4b4b4, Ta5d6ff"Ta5d6ffWELCOME timeoutTa5d6ff"Tb4b4b4)
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4, Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8fflink Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflinkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_send_helloTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4)Tb4b4b4:
Te6edf3body Tff7b72= Tb4b4b4{
Te6edf3protoTff7b72.Td2a8ffB_HELLO_NAMETb4b4b4: Te6edf3protoTff7b72.Td2a8ffHELLO_CLIENT_NAMETb4b4b4,
Te6edf3protoTff7b72.Td2a8ffB_HELLO_VERTb4b4b4: Te6edf3protoTff7b72.Td2a8ffHELLO_CLIENT_VERSIONTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffB_HELLO_CAPSTb4b4b4: Tb4b4b4{
Te6edf3protoTff7b72.Td2a8ffCAP_RESOURCE_ENVELOPETb4b4b4: Tff7b72TrueTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffCAP_ACTIONTb4b4b4: Tff7b72TrueTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}
Te6edf3env Tff7b72= Te6edf3protoTff7b72.Td2a8ffmake_envelopeTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffT_HELLOTb4b4b4,
Te6edf3srcTff7b72=Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3bodyTff7b72=Te6edf3bodyTb4b4b4,
Tb4b4b4)
Te6edf3nick Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_effective_nickTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3nickTb4b4b4:
Te6edf3envTb4b4b4[Te6edf3protoTff7b72.Td2a8ffK_NICKTb4b4b4] Tff7b72= Te6edf3nick
Te6edf3payload Tff7b72= Te6edf3protoTff7b72.Td2a8ffencodeTb4b4b4(Te6edf3envTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_raw_sendTb4b4b4(Te6edf3linkTb4b4b4, Te6edf3payloadTb4b4b4)

Tff7b72def Td2a8ff_on_closedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_stop_helloTff7b72.Td2a8ffsetTb4b4b4(Tb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3was_welcomed Tff7b72= Tff7b72selfTff7b72.Td2a8ffwelcomed
Te6edf3rooms Tff7b72= Tffa657listTb4b4b4(Tff7b72selfTff7b72.Td2a8ffroomsTb4b4b4)
Te6edf3manual Tff7b72= Tff7b72selfTff7b72.Td2a8ff_manual_disconnect
Tff7b72selfTff7b72.Td2a8fflink Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffwelcomed Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffmotd Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffmembersTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_resource_expectationsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_pending_joinsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_pending_partsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_silent_joinsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_silent_who_roomsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Te6edf3should_reconnect Tff7b72= Tff7b72selfTff7b72.Td2a8ffauto_reconnect Tff7b72and Tff7b72not Tff7b72selfTff7b72.Td2a8ff_manual_disconnect
Tff7b72if Te6edf3was_welcomed Tff7b72and Te6edf3roomsTb4b4b4:
Te6edf3text Tff7b72= Ta5d6ff"Ta5d6ffDisconnected from hubTa5d6ff" Tff7b72if Te6edf3manual Tff7b72else Ta5d6ff"Ta5d6ffConnection lostTa5d6ff"
Tff7b72selfTff7b72.Td2a8ff_record_connection_eventTb4b4b4(Te6edf3textTb4b4b4, Te6edf3roomsTff7b72=Te6edf3roomsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_DISCONNECTEDTb4b4b4, Ta5d6ff"Ta5d6ffDisconnectedTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3should_reconnectTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_schedule_reconnectTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_schedule_reconnectTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_reconnect_attempts Tff7b72+Tff7b72= T79c0ff1
Te6edf3backoff Tff7b72= Tffa657minTb4b4b4(T79c0ff60.0Tb4b4b4, Tffa657maxTb4b4b4(T79c0ff1.0Tb4b4b4, T79c0ff2.0 Tff7b72*Tff7b72* Tffa657minTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_reconnect_attemptsTb4b4b4, T79c0ff6Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_reconnect_timer Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_reconnect_timerTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ff_reconnect_timer Tff7b72= Te6edf3threadingTff7b72.Td2a8ffTimerTb4b4b4(Te6edf3backoffTb4b4b4, Tff7b72selfTff7b72.Td2a8ff_fire_reconnectTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_reconnect_timerTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_reconnect_timerTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(
Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_DISCONNECTEDTb4b4b4,
Ta5d6ff"Ta5d6ffReconnect in Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Tffa657intTb4b4b4(Te6edf3backoffTb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ffsTa5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72def Td2a8ff_fire_reconnectTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_reconnect_timer Tff7b72= Tff7b72None
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_manual_disconnect Tff7b72or Tff7b72not Tff7b72selfTff7b72.Td2a8ffauto_reconnectTb4b4b4:
Tff7b72return
Tff7b72selfTff7b72.Td2a8ffconnectTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffdisconnectTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_stop_helloTff7b72.Td2a8ffsetTb4b4b4(Tb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_manual_disconnect Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_reconnect_attempts Tff7b72= T79c0ff0
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_reconnect_timer Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_reconnect_timerTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_reconnect_timer Tff7b72= Tff7b72None
Te6edf3link Tff7b72= Tff7b72selfTff7b72.Td2a8fflink
Tff7b72selfTff7b72.Td2a8fflink Tff7b72= Tff7b72None
Tff7b72if Te6edf3link Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_DISCONNECTEDTb4b4b4, Ta5d6ff"Ta5d6ffDisconnectedTa5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffset_auto_reconnectTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3enabledTb4b4b4, Te6edf3saveTff7b72=Tff7b72TrueTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffauto_reconnect Tff7b72= Tffa657boolTb4b4b4(Te6edf3enabledTb4b4b4)
Tff7b72if Tff7b72not Te6edf3enabled Tff7b72and Tff7b72selfTff7b72.Td2a8ff_reconnect_timer Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_reconnect_timerTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_reconnect_timer Tff7b72= Tff7b72None
Tff7b72if Te6edf3saveTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffset_auto_listTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3enabledTb4b4b4, Te6edf3saveTff7b72=Tff7b72TrueTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffauto_list Tff7b72= Tffa657boolTb4b4b4(Te6edf3enabledTb4b4b4)
Te6edf3should_list Tff7b72= Tff7b72selfTff7b72.Td2a8ffauto_list Tff7b72and Tff7b72selfTff7b72.Td2a8ffwelcomed
Tff7b72if Te6edf3saveTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72if Te6edf3should_listTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_request_room_listTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffrequest_room_listTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Request a fresh public room list from the hub (/list).

The hub reply replaces available_rooms (adds new rooms and drops
removed ones). The list notice is silent so it does not appear in
chat history.
"""
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_silent_list_pending Tff7b72+Tff7b72= T79c0ff1
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsend_commandTb4b4b4(Ta5d6ff"Ta5d6ff/listTa5d6ff"Tb4b4b4, Te6edf3roomTff7b72=Tff7b72NoneTb4b4b4, Te6edf3record_localTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_silent_list_pending Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_silent_list_pending Tff7b72-Tff7b72= T79c0ff1
Tff7b72raise

Tff7b72def Td2a8ff_request_room_listTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrequest_room_listTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffset_auto_whoTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3enabledTb4b4b4, Te6edf3saveTff7b72=Tff7b72TrueTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffauto_who Tff7b72= Tffa657boolTb4b4b4(Te6edf3enabledTb4b4b4)
Tff7b72if Te6edf3saveTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffget_effective_nickTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Tff7b72selfTff7b72.Td2a8ffnick_overrideTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Tff7b72selfTff7b72.Td2a8ffnick_overrideTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffnick_override
Tff7b72return Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffget_nicknameTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffset_nick_overrideTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3nickTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Te6edf3nick Tff7b72is Tff7b72None Tff7b72or Tb4b4b4(Tffa657isinstanceTb4b4b4(Te6edf3nickTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3nick Tff7b72== Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffnick_override Tff7b72= Tff7b72None
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffnick_override Tff7b72= Tffa657strTb4b4b4(Te6edf3nickTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ff_packet_would_fitTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4, Te6edf3payloadTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3pkt Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Te6edf3linkTb4b4b4, Te6edf3payloadTb4b4b4)
Te6edf3pktTff7b72.Td2a8ffpackTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72True
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72False

Tff7b72def Td2a8ff_raw_sendTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4, Te6edf3payloadTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3linkTb4b4b4, Te6edf3_LoopbackEndpointTb4b4b4)Tb4b4b4:
Te6edf3linkTff7b72.Td2a8fffrom_clientTb4b4b4(Te6edf3payloadTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Te6edf3linkTb4b4b4, Te6edf3payloadTb4b4b4)Tff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_send_envTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3link Tff7b72= Tff7b72selfTff7b72.Td2a8fflink
Tff7b72if Te6edf3link Tff7b72is Tff7b72None Tff7b72or Te6edf3linkTff7b72.Td2a8ffstatus Tff7b72!= Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffACTIVETb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffnot connectedTa5d6ff"
Tff7b72raise Tf85149RuntimeErrorTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3payload Tff7b72= Te6edf3protoTff7b72.Td2a8ffencodeTb4b4b4(Te6edf3envTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3linkTb4b4b4, Te6edf3_LoopbackEndpointTb4b4b4)Tb4b4b4:
Te6edf3linkTff7b72.Td2a8fffrom_clientTb4b4b4(Te6edf3payloadTb4b4b4)
Tff7b72return
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_packet_would_fitTb4b4b4(Te6edf3linkTb4b4b4, Te6edf3payloadTb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffmessage exceeds link MTUTa5d6ff"
Tff7b72raise Tf85149RuntimeErrorTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Te6edf3linkTb4b4b4, Te6edf3payloadTb4b4b4)Tff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffjoin_roomTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4, Te6edf3keyTff7b72=Tff7b72NoneTb4b4b4, Te6edf3silentTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Te6edf3body Tff7b72= Tff7b72None
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3keyTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Te6edf3stripped Tff7b72= Te6edf3keyTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3strippedTb4b4b4:
Te6edf3body Tff7b72= Te6edf3stripped
Te6edf3env Tff7b72= Te6edf3protoTff7b72.Td2a8ffmake_envelopeTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffT_JOINTb4b4b4,
Te6edf3srcTff7b72=Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3roomTff7b72=Te6edf3rTb4b4b4,
Te6edf3bodyTff7b72=Te6edf3bodyTb4b4b4,
Tb4b4b4)
Te6edf3nick Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_effective_nickTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3nickTb4b4b4:
Te6edf3envTb4b4b4[Te6edf3protoTff7b72.Td2a8ffK_NICKTb4b4b4] Tff7b72= Te6edf3nick
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_pending_joinsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72if Te6edf3silentTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_silent_joinsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_send_envTb4b4b4(Te6edf3envTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Te6edf3r Tff7b72not Tff7b72in Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4[Te6edf3rTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffsend_commandTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3textTb4b4b4, Te6edf3roomTff7b72=Tff7b72NoneTb4b4b4, Te6edf3record_localTff7b72=Tff7b72TrueTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3textTb4b4b4, Tffa657strTb4b4b4) Tff7b72or Tff7b72not Te6edf3textTff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ff/Ta5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffcommand must start with /Ta5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3r Tff7b72= Tff7b72None
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Te6edf3nick Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_effective_nickTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3record_localTb4b4b4:
Te6edf3history_text Tff7b72= Tff7b72selfTff7b72.Td2a8ff_redact_command_for_historyTb4b4b4(Te6edf3textTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_record_messageTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffRRCMessageTb4b4b4(
Ta5d6ff"Ta5d6ffmsgTa5d6ff"Tb4b4b4,
Te6edf3rTb4b4b4,
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3nickTb4b4b4,
Te6edf3history_textTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3localTff7b72=Tff7b72TrueTb4b4b4,
Tb4b4b4)
Te6edf3env Tff7b72= Te6edf3protoTff7b72.Td2a8ffmake_envelopeTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffT_MSGTb4b4b4,
Te6edf3srcTff7b72=Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3roomTff7b72=Te6edf3rTb4b4b4,
Te6edf3bodyTff7b72=Te6edf3textTb4b4b4,
Tb4b4b4)
Tff7b72if Te6edf3nickTb4b4b4:
Te6edf3envTb4b4b4[Te6edf3protoTff7b72.Td2a8ffK_NICKTb4b4b4] Tff7b72= Te6edf3nick
Tff7b72selfTff7b72.Td2a8ff_send_envTb4b4b4(Te6edf3envTb4b4b4)

Tf0883e@staticmethod
Tff7b72def Td2a8ff_redact_command_for_historyTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
T8b949e"""Omit +k secrets from locally recorded command history."""
Te6edf3parts Tff7b72= Te6edf3textTff7b72.Td2a8ffsplitTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3partsTb4b4b4) Tff7b72>Tff7b72= T79c0ff4 Tff7b72and Te6edf3partsTb4b4b4[T79c0ff0Tb4b4b4]Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ff/modeTa5d6ff" Tff7b72and Te6edf3partsTb4b4b4[T79c0ff2Tb4b4b4]Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ff+kTa5d6ff"Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff Ta5d6ff"Tff7b72.Td2a8ffjoinTb4b4b4(Tb4b4b4[Tff7b72*Te6edf3partsTb4b4b4[Tb4b4b4:T79c0ff3Tb4b4b4]Tb4b4b4, Ta5d6ff"Ta5d6ff***Ta5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72return Te6edf3text

Tff7b72def Td2a8ffsend_pingTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Te6edf3body Tff7b72= Te6edf3osTff7b72.Td2a8ffurandomTb4b4b4(T79c0ff8Tb4b4b4)
Te6edf3env Tff7b72= Te6edf3protoTff7b72.Td2a8ffmake_envelopeTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffT_PINGTb4b4b4,
Te6edf3srcTff7b72=Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3bodyTff7b72=Te6edf3bodyTb4b4b4,
Tb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3now Tff7b72= Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_pending_pingsTb4b4b4[Te6edf3bodyTb4b4b4] Tff7b72= Tb4b4b4(Te6edf3nowTb4b4b4, Te6edf3roomTb4b4b4)
Te6edf3expired Tff7b72= Tb4b4b4[Te6edf3k Tff7b72for Te6edf3kTb4b4b4, Te6edf3v Tff7b72in Tff7b72selfTff7b72.Td2a8ff_pending_pingsTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4) Tff7b72if Te6edf3now Tff7b72- Te6edf3vTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72> T79c0ff15000Tb4b4b4]
Tff7b72for Te6edf3k Tff7b72in Te6edf3expiredTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_pending_pingsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3kTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_send_envTb4b4b4(Te6edf3envTb4b4b4)
Tff7b72return Te6edf3body

Tff7b72def Td2a8ffpart_roomTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Te6edf3room_n Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Te6edf3env Tff7b72= Te6edf3protoTff7b72.Td2a8ffmake_envelopeTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffT_PARTTb4b4b4,
Te6edf3srcTff7b72=Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3roomTff7b72=Te6edf3room_nTb4b4b4,
Tb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_pending_partsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3room_nTb4b4b4)
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_send_envTb4b4b4(Te6edf3envTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffroomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3room_nTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffpopTb4b4b4(Te6edf3room_nTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3room_nTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_countsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3room_nTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmention_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3room_nTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmembersTff7b72.Td2a8ffpopTb4b4b4(Te6edf3room_nTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_delete_historyTb4b4b4(Te6edf3room_nTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffsend_messageTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4, Te6edf3textTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3textTb4b4b4, Tffa657strTb4b4b4) Tff7b72or Tff7b72not Te6edf3textTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffmessage text must be non-emptyTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3textTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4) Tff7b72> Tff7b72selfTff7b72.Td2a8ffmax_msg_body_bytesTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffmessage too long for hub limitTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3env Tff7b72= Te6edf3protoTff7b72.Td2a8ffmake_envelopeTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffT_MSGTb4b4b4,
Te6edf3srcTff7b72=Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3roomTff7b72=Te6edf3rTb4b4b4,
Te6edf3bodyTff7b72=Te6edf3textTb4b4b4,
Tb4b4b4)
Te6edf3nick Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_effective_nickTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3nickTb4b4b4:
Te6edf3envTb4b4b4[Te6edf3protoTff7b72.Td2a8ffK_NICKTb4b4b4] Tff7b72= Te6edf3nick
Te6edf3mid Tff7b72= Te6edf3envTb4b4b4[Te6edf3protoTff7b72.Td2a8ffK_IDTb4b4b4]
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3midTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_sent_idsTff7b72.Td2a8ffappendTb4b4b4(Tffa657bytesTb4b4b4(Te6edf3midTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_record_messageTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffRRCMessageTb4b4b4(
Ta5d6ff"Ta5d6ffmsgTa5d6ff"Tb4b4b4,
Te6edf3rTb4b4b4,
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3nickTb4b4b4,
Te6edf3textTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3localTff7b72=Tff7b72TrueTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_send_envTb4b4b4(Te6edf3envTb4b4b4)
Tff7b72return Te6edf3mid

Tff7b72def Td2a8ffsend_actionTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4, Te6edf3textTb4b4b4)Tb4b4b4:
Te6edf3r Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3textTb4b4b4, Tffa657strTb4b4b4) Tff7b72or Tff7b72not Te6edf3textTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffaction text must be non-emptyTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3textTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4) Tff7b72> Tff7b72selfTff7b72.Td2a8ffmax_msg_body_bytesTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffaction too long for hub limitTa5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3env Tff7b72= Te6edf3protoTff7b72.Td2a8ffmake_envelopeTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffT_ACTIONTb4b4b4,
Te6edf3srcTff7b72=Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3roomTff7b72=Te6edf3rTb4b4b4,
Te6edf3bodyTff7b72=Te6edf3textTb4b4b4,
Tb4b4b4)
Te6edf3nick Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_effective_nickTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3nickTb4b4b4:
Te6edf3envTb4b4b4[Te6edf3protoTff7b72.Td2a8ffK_NICKTb4b4b4] Tff7b72= Te6edf3nick
Te6edf3mid Tff7b72= Te6edf3envTb4b4b4[Te6edf3protoTff7b72.Td2a8ffK_IDTb4b4b4]
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3midTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_sent_idsTff7b72.Td2a8ffappendTb4b4b4(Tffa657bytesTb4b4b4(Te6edf3midTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_record_messageTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffRRCMessageTb4b4b4(
Ta5d6ff"Ta5d6ffactionTa5d6ff"Tb4b4b4,
Te6edf3rTb4b4b4,
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3nickTb4b4b4,
Te6edf3textTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3localTff7b72=Tff7b72TrueTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_send_envTb4b4b4(Te6edf3envTb4b4b4)
Tff7b72return Te6edf3mid

Tff7b72def Td2a8ff_per_room_capTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3v Tff7b72= Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffhistory_per_room_cap
Tff7b72tryTb4b4b4:
Te6edf3v Tff7b72= Tffa657intTb4b4b4(Te6edf3vTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72return Te6edf3v Tff7b72if Te6edf3v Tff7b72> T79c0ff0 Tff7b72else Tff7b72None

Tff7b72def Td2a8ff_filter_historyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tffa657boolTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8fffilter_loaded_historyTb4b4b4)

Tff7b72def Td2a8ff_ephemeral_notices_historyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffephemeral_notices

Tff7b72def Td2a8ff_entry_forTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3msgTb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4{
Te6edf3H_KINDTb4b4b4: Te6edf3msgTff7b72.Td2a8ffkindTb4b4b4,
Te6edf3H_SRCTb4b4b4: Tffa657bytesTb4b4b4(Te6edf3msgTff7b72.Td2a8ffsrcTb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3msgTff7b72.Td2a8ffsrcTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Te6edf3H_NICKTb4b4b4: Te6edf3msgTff7b72.Td2a8ffnick Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3msgTff7b72.Td2a8ffnickTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Te6edf3H_TEXTTb4b4b4: Te6edf3msgTff7b72.Td2a8fftext Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3msgTff7b72.Td2a8fftextTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Ta5d6ff"Ta5d6ff"Tb4b4b4,
Te6edf3H_TSTb4b4b4: Tffa657intTb4b4b4(Te6edf3msgTff7b72.Td2a8fftsTb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3msgTff7b72.Td2a8fftsTb4b4b4, Tffa657intTb4b4b4) Tff7b72else Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3H_MENTIONTb4b4b4: Tffa657boolTb4b4b4(Tffa657getattrTb4b4b4(Te6edf3msgTb4b4b4, Ta5d6ff"Ta5d6ffmentionTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4}

Tff7b72def Td2a8ff_msg_from_entryTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4, Te6edf3entryTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3entryTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72None
Te6edf3m Tff7b72= Te6edf3protoTff7b72.Td2a8ffRRCMessageTb4b4b4(
Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_KINDTb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_KINDTb4b4b4)Tb4b4b4, Tffa657strTb4b4b4) Tff7b72else Ta5d6ff"Ta5d6ffmsgTa5d6ff"Tb4b4b4,
Te6edf3roomTb4b4b4,
Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_SRCTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_SRCTb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)
Tff7b72else Tff7b72NoneTb4b4b4,
Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_NICKTb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_NICKTb4b4b4)Tb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_TEXTTb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_TEXTTb4b4b4)Tb4b4b4, Tffa657strTb4b4b4) Tff7b72else Ta5d6ff"Ta5d6ff"Tb4b4b4,
Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_TSTb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_TSTb4b4b4)Tb4b4b4, Tffa657intTb4b4b4) Tff7b72else T79c0ff0Tb4b4b4,
Tb4b4b4)
Te6edf3mTff7b72.Td2a8ffmention Tff7b72= Tffa657boolTb4b4b4(Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Te6edf3H_MENTIONTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3m

Tff7b72def Td2a8ff_persistable_roomTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72return Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3room Tff7b72and Te6edf3room Tff7b72!= Ta5d6ff"Ta5d6ff*Ta5d6ff"

Tff7b72def Td2a8ff_append_historyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4, Te6edf3msgTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_persistable_roomTb4b4b4(Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_ensure_history_dirTb4b4b4(Tff7b72selfTb4b4b4)
Te6edf3path Tff7b72= Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_history_pathTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3pathTb4b4b4, Ta5d6ff"Ta5d6ffabTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3protoTff7b72.Td2a8ffencodeTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_entry_forTb4b4b4(Te6edf3msgTb4b4b4)Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_history_write_failed Tff7b72= Tff7b72False
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_history_write_failedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_history_write_failed Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_logTb4b4b4(
Ta5d6ff"Ta5d6ffhistory persistence failed, suppressing further warnings Ta5d6ff"
Ta5d6ff"Ta5d6ffuntil recovery: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4,
Tb4b4b4)

Tff7b72def Td2a8ff_delete_historyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_persistable_roomTb4b4b4(Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3path Tff7b72= Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_history_pathTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3pathTb4b4b4)

Tff7b72def Td2a8ff_load_historyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3rooms Tff7b72= Tffa657listTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffkeysTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72for Te6edf3room Tff7b72in Te6edf3roomsTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_persistable_roomTb4b4b4(Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3path Tff7b72= Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_history_pathTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3window Tff7b72= Te6edf3dequeTb4b4b4(Te6edf3maxlenTff7b72=Tff7b72selfTff7b72.Td2a8ff_per_room_capTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3decode_error Tff7b72= Tff7b72None
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Tff7b72while Tff7b72TrueTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3windowTff7b72.Td2a8ffappendTb4b4b4(Te6edf3protoTff7b72.Td2a8ffloadTb4b4b4(Te6edf3fTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149EOFErrorTb4b4b4:
Tff7b72break
Tff7b72except Tf85149Exception Tff7b72as Te6edf3exTb4b4b4:
Te6edf3decode_error Tff7b72= Te6edf3ex
Tff7b72break
Tff7b72except Tf85149OSError Tff7b72as Te6edf3exTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_logTb4b4b4(
Ta5d6ff"Ta5d6ffhistory load failed for #Ta5d6ff" Tff7b72+ Te6edf3room Tff7b72+ Ta5d6ff"Ta5d6ff: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3exTb4b4b4)Tb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4,
Tb4b4b4)
Tff7b72continue
Tff7b72if Te6edf3decode_error Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_logTb4b4b4(
Ta5d6ff"Ta5d6ffhistory file for #Ta5d6ff"
Tff7b72+ Te6edf3room
Tff7b72+ Ta5d6ff"Ta5d6ff is corrupt, truncating to last Ta5d6ff"
Tff7b72+ Tffa657strTb4b4b4(Tffa657lenTb4b4b4(Te6edf3windowTb4b4b4)Tb4b4b4)
Tff7b72+ Ta5d6ff"Ta5d6ff valid messages: Ta5d6ff"
Tff7b72+ Tffa657strTb4b4b4(Te6edf3decode_errorTb4b4b4)Tb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4,
Tb4b4b4)
Te6edf3msgs Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3filter_msgs Tff7b72= Tff7b72selfTff7b72.Td2a8ff_filter_historyTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3e Tff7b72in Te6edf3windowTb4b4b4:
Te6edf3m Tff7b72= Tff7b72selfTff7b72.Td2a8ff_msg_from_entryTb4b4b4(Te6edf3roomTb4b4b4, Te6edf3eTb4b4b4)
Tff7b72if Te6edf3m Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72continue
Tff7b72if Te6edf3filter_msgs Tff7b72and Te6edf3mTff7b72.Td2a8ffkind Tff7b72in Tb4b4b4(Ta5d6ff"Ta5d6ffsystemTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffnoticeTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3mTff7b72.Td2a8ffseq Tff7b72= Tff7b72selfTff7b72.Td2a8ff_next_seqTb4b4b4(Tb4b4b4)
Te6edf3msgsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3mTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4[Te6edf3roomTb4b4b4] Tff7b72= Te6edf3msgs

Tff7b72def Td2a8ff_clean_historyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3cleaned Tff7b72= Tff7b72False
Te6edf3remove_after Tff7b72= Tff7b72selfTff7b72.Td2a8ff_ephemeral_notices_historyTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3now Tff7b72> Tff7b72selfTff7b72.Td2a8ff_last_history_clean Tff7b72+ Tff7b72selfTff7b72.Td2a8ffCLEAN_HISTORY_INTERVALTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72for Te6edf3r Tff7b72in Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4:
Te6edf3old Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3m Tff7b72in Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4[Te6edf3rTb4b4b4]Tb4b4b4:
Te6edf3age Tff7b72= Te6edf3now Tff7b72- Te6edf3mTff7b72.Td2a8ffts Tff7b72/ T79c0ff1000.0
Tff7b72if Te6edf3mTff7b72.Td2a8ffkind Tff7b72in Tb4b4b4(Ta5d6ff"Ta5d6ffsystemTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffnoticeTa5d6ff"Tb4b4b4) Tff7b72and Te6edf3age Tff7b72> Te6edf3remove_afterTb4b4b4:
Te6edf3oldTff7b72.Td2a8ffaddTb4b4b4(Te6edf3mTb4b4b4)
Tff7b72for Te6edf3m Tff7b72in Te6edf3oldTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4[Te6edf3rTb4b4b4]Tff7b72.Td2a8ffremoveTb4b4b4(Te6edf3mTb4b4b4)
Te6edf3cleaned Tff7b72= Tff7b72True
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fftrace_exceptionTb4b4b4(Te6edf3eTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_last_history_clean Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3cleanedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffclean_last_removed Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_record_messageTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3msgTb4b4b4, Te6edf3localTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Te6edf3cap Tff7b72= Tff7b72selfTff7b72.Td2a8ff_per_room_capTb4b4b4(Tb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3msgTff7b72.Td2a8ffseq Tff7b72= Tff7b72selfTff7b72.Td2a8ff_next_seqTb4b4b4(Tb4b4b4)
Te6edf3buf Tff7b72= Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffsetdefaultTb4b4b4(Te6edf3msgTff7b72.Td2a8ffroom Tff7b72or Ta5d6ff"Ta5d6ff*Ta5d6ff"Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)
Te6edf3bufTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Te6edf3cap Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3bufTb4b4b4) Tff7b72> Te6edf3capTb4b4b4:
Tff7b72del Te6edf3bufTb4b4b4[Tb4b4b4: Tffa657lenTb4b4b4(Te6edf3bufTb4b4b4) Tff7b72- Te6edf3capTb4b4b4]
Tff7b72if Tb4b4b4(
Tff7b72not Te6edf3local
Tff7b72and Te6edf3msgTff7b72.Td2a8ffroom
Tff7b72and Te6edf3msgTff7b72.Td2a8ffroom Tff7b72!= Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffactive_room_forTb4b4b4(Tff7b72selfTb4b4b4)
Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_bump_unreadTb4b4b4(Te6edf3msgTff7b72.Td2a8ffroomTb4b4b4)
Tff7b72if Te6edf3msgTff7b72.Td2a8ffmentionTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmention_roomsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3msgTff7b72.Td2a8ffroomTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_messagesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3msgTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_append_historyTb4b4b4(Te6edf3msgTff7b72.Td2a8ffroomTb4b4b4, Te6edf3msgTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_clean_historyTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_record_systemTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4, Te6edf3textTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3roomTb4b4b4:
Tff7b72return
Te6edf3msg Tff7b72= Te6edf3protoTff7b72.Td2a8ffRRCMessageTb4b4b4(Ta5d6ff"Ta5d6ffsystemTa5d6ff"Tb4b4b4, Te6edf3roomTb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4, Te6edf3textTb4b4b4, Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3cap Tff7b72= Tff7b72selfTff7b72.Td2a8ff_per_room_capTb4b4b4(Tb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3msgTff7b72.Td2a8ffseq Tff7b72= Tff7b72selfTff7b72.Td2a8ff_next_seqTb4b4b4(Tb4b4b4)
Te6edf3buf Tff7b72= Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffsetdefaultTb4b4b4(Te6edf3roomTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)
Te6edf3bufTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Te6edf3cap Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3bufTb4b4b4) Tff7b72> Te6edf3capTb4b4b4:
Tff7b72del Te6edf3bufTb4b4b4[Tb4b4b4: Tffa657lenTb4b4b4(Te6edf3bufTb4b4b4) Tff7b72- Te6edf3capTb4b4b4]
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_messagesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3msgTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_append_historyTb4b4b4(Te6edf3roomTb4b4b4, Te6edf3msgTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_clean_historyTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_record_connection_eventTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3textTb4b4b4, Te6edf3roomsTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
T8b949e"""Write a connection status line into each joined room timeline."""
Tff7b72if Te6edf3rooms Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3rooms Tff7b72= Tffa657listTb4b4b4(Tff7b72selfTff7b72.Td2a8ffroomsTb4b4b4)
Tff7b72for Te6edf3room Tff7b72in Te6edf3roomsTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_record_systemTb4b4b4(Te6edf3roomTb4b4b4, Te6edf3textTb4b4b4)

Tff7b72def Td2a8ff_record_noticeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3msgTb4b4b4)Tb4b4b4:
Te6edf3target_room Tff7b72= Te6edf3msgTff7b72.Td2a8ffroom
Tff7b72if Tff7b72not Te6edf3target_roomTb4b4b4:
Te6edf3target_room Tff7b72= Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffactive_room_forTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72if Te6edf3target_roomTb4b4b4:
Te6edf3msgTff7b72.Td2a8ffroom Tff7b72= Te6edf3target_room

Te6edf3cap Tff7b72= Tff7b72selfTff7b72.Td2a8ff_per_room_capTb4b4b4(Tb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3msgTff7b72.Td2a8ffseq Tff7b72= Tff7b72selfTff7b72.Td2a8ff_next_seqTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffnoticesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffnoticesTb4b4b4) Tff7b72> T79c0ff200Tb4b4b4:
Tff7b72del Tff7b72selfTff7b72.Td2a8ffnoticesTb4b4b4[Tb4b4b4: Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffnoticesTb4b4b4) Tff7b72- T79c0ff200Tb4b4b4]
Tff7b72if Te6edf3target_roomTb4b4b4:
Te6edf3buf Tff7b72= Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffsetdefaultTb4b4b4(Te6edf3target_roomTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)
Te6edf3bufTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Te6edf3cap Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3bufTb4b4b4) Tff7b72> Te6edf3capTb4b4b4:
Tff7b72del Te6edf3bufTb4b4b4[Tb4b4b4: Tffa657lenTb4b4b4(Te6edf3bufTb4b4b4) Tff7b72- Te6edf3capTb4b4b4]
Tff7b72if Te6edf3target_room Tff7b72!= Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffactive_room_forTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_bump_unreadTb4b4b4(Te6edf3target_roomTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_messagesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3msgTb4b4b4)
Tff7b72if Te6edf3target_roomTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_append_historyTb4b4b4(Te6edf3target_roomTb4b4b4, Te6edf3msgTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_clean_historyTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffget_messagesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72return Tffa657listTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffgetTb4b4b4(Te6edf3roomTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ff_on_packetTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3env Tff7b72= Te6edf3protoTff7b72.Td2a8ffdecodeTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_logTb4b4b4(Ta5d6ff"Ta5d6ffdecode failed: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72return
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3envTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3t Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_TTb4b4b4)
Tff7b72if Te6edf3t Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return

Te6edf3handler Tff7b72= Tff7b72selfTff7b72.Td2a8ff_PACKET_HANDLERSTff7b72.Td2a8ffgetTb4b4b4(Te6edf3tTb4b4b4)
Tff7b72if Te6edf3handler Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3handlerTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)

Tff7b72def Td2a8ff_handle_pingTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3pong Tff7b72= Te6edf3protoTff7b72.Td2a8ffmake_envelopeTb4b4b4(
Te6edf3protoTff7b72.Td2a8ffT_PONGTb4b4b4,
Te6edf3srcTff7b72=Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4,
Te6edf3bodyTff7b72=Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_BODYTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_send_envTb4b4b4(Te6edf3pongTb4b4b4)

Tff7b72def Td2a8ff_handle_pongTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Te6edf3body Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_BODYTb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3bodyTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3key Tff7b72= Tffa657bytesTb4b4b4(Te6edf3bodyTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3pending Tff7b72= Tff7b72selfTff7b72.Td2a8ff_pending_pingsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3keyTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72if Te6edf3pending Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3sent_msTb4b4b4, Te6edf3room Tff7b72= Te6edf3pending
Te6edf3rtt_ms Tff7b72= Tffa657maxTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3sent_msTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_record_systemTb4b4b4(Te6edf3roomTb4b4b4, Ta5d6ff"Ta5d6ffPong from hub: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3rtt_msTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff msTa5d6ff"Tb4b4b4)

Tff7b72def Td2a8ff_handle_welcomeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwelcomed Tff7b72= Tff7b72True
Te6edf3body Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_BODYTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3bodyTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3hub_name Tff7b72= Te6edf3bodyTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffB_WELCOME_HUBTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3hub_nameTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhub_name Tff7b72= Te6edf3hub_name
Te6edf3ver Tff7b72= Te6edf3bodyTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffB_WELCOME_VERTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3verTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhub_version Tff7b72= Te6edf3ver
Te6edf3caps Tff7b72= Te6edf3bodyTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffB_WELCOME_CAPSTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3capsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhub_caps Tff7b72= Tffa657dictTb4b4b4(Te6edf3capsTb4b4b4)
Te6edf3limits Tff7b72= Te6edf3bodyTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffB_WELCOME_LIMITSTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3limitsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_apply_limitsTb4b4b4(Te6edf3limitsTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3was_reconnect Tff7b72= Tff7b72selfTff7b72.Td2a8ff_had_session
Tff7b72selfTff7b72.Td2a8ff_reconnect_attempts Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_had_session Tff7b72= Tff7b72True
Te6edf3rooms Tff7b72= Tffa657listTb4b4b4(Tff7b72selfTff7b72.Td2a8ffroomsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_set_statusTb4b4b4(Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_CONNECTEDTb4b4b4, Ta5d6ff"Ta5d6ffConnectedTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3was_reconnect Tff7b72and Te6edf3roomsTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_record_connection_eventTb4b4b4(Ta5d6ff"Ta5d6ffReconnected to hubTa5d6ff"Tb4b4b4, Te6edf3roomsTff7b72=Te6edf3roomsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_on_welcomeTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffauto_listTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_request_room_listTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_apply_limitsTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3limitsTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3protoTff7b72.Td2a8ffL_MAX_NICK_BYTES Tff7b72in Te6edf3limitsTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmax_nick_bytes Tff7b72= Tffa657intTb4b4b4(Te6edf3limitsTb4b4b4[Te6edf3protoTff7b72.Td2a8ffL_MAX_NICK_BYTESTb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3protoTff7b72.Td2a8ffL_MAX_ROOM_NAME_BYTES Tff7b72in Te6edf3limitsTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmax_room_name_bytes Tff7b72= Tffa657intTb4b4b4(Te6edf3limitsTb4b4b4[Te6edf3protoTff7b72.Td2a8ffL_MAX_ROOM_NAME_BYTESTb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3protoTff7b72.Td2a8ffL_MAX_MSG_BODY_BYTES Tff7b72in Te6edf3limitsTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmax_msg_body_bytes Tff7b72= Tffa657intTb4b4b4(Te6edf3limitsTb4b4b4[Te6edf3protoTff7b72.Td2a8ffL_MAX_MSG_BODY_BYTESTb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3protoTff7b72.Td2a8ffL_MAX_ROOMS_PER_SESSION Tff7b72in Te6edf3limitsTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmax_rooms_per_session Tff7b72= Tffa657intTb4b4b4(Te6edf3limitsTb4b4b4[Te6edf3protoTff7b72.Td2a8ffL_MAX_ROOMS_PER_SESSIONTb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3protoTff7b72.Td2a8ffL_RATE_LIMIT_MSGS_PER_MINUTE Tff7b72in Te6edf3limitsTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrate_limit_msgs_per_minute Tff7b72= Tffa657intTb4b4b4(
Te6edf3limitsTb4b4b4[Te6edf3protoTff7b72.Td2a8ffL_RATE_LIMIT_MSGS_PER_MINUTETb4b4b4]Tb4b4b4,
Tb4b4b4)

Tff7b72def Td2a8ff_own_hashTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhash Tff7b72if Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffidentity Tff7b72is Tff7b72not Tff7b72None Tff7b72else Tff7b72None

Tff7b72def Td2a8ff_handle_joinedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Te6edf3room Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_ROOMTb4b4b4)
Tff7b72if Tff7b72not Tb4b4b4(Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3r Tff7b72= Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Te6edf3body Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_BODYTb4b4b4)
Te6edf3joiner_nick Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_NICKTb4b4b4)
Te6edf3own_hash Tff7b72= Tff7b72selfTff7b72.Td2a8ff_own_hashTb4b4b4(Tb4b4b4)

Te6edf3body_hashes Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3bodyTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Te6edf3body_hashes Tff7b72= Tb4b4b4[Tffa657bytesTb4b4b4(Te6edf3eTb4b4b4) Tff7b72for Te6edf3e Tff7b72in Te6edf3body Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3eTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4]

Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3self_join Tff7b72= Te6edf3r Tff7b72in Tff7b72selfTff7b72.Td2a8ff_pending_joins
Te6edf3silent Tff7b72= Te6edf3r Tff7b72in Tff7b72selfTff7b72.Td2a8ff_silent_joins
Tff7b72if Te6edf3self_joinTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_pending_joinsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72if Te6edf3silentTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_silent_joinsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffroomsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72if Te6edf3r Tff7b72not Tff7b72in Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4[Te6edf3rTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3members Tff7b72= Tff7b72selfTff7b72.Td2a8ffmembersTff7b72.Td2a8ffsetdefaultTb4b4b4(Te6edf3rTb4b4b4, Tffa657setTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72for Te6edf3h Tff7b72in Te6edf3body_hashesTb4b4b4:
Te6edf3membersTff7b72.Td2a8ffaddTb4b4b4(Te6edf3hTb4b4b4)
Tff7b72if Te6edf3own_hash Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3membersTff7b72.Td2a8ffaddTb4b4b4(Te6edf3own_hashTb4b4b4)

Tff7b72if Tb4b4b4(
Tb4b4b4(Tff7b72not Te6edf3self_joinTb4b4b4)
Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3joiner_nickTb4b4b4, Tffa657strTb4b4b4)
Tff7b72and Te6edf3joiner_nick
Tff7b72and Tffa657lenTb4b4b4(Te6edf3body_hashesTb4b4b4) Tff7b72== T79c0ff1
Tb4b4b4)Tb4b4b4:
Te6edf3jh Tff7b72= Te6edf3body_hashesTb4b4b4[T79c0ff0Tb4b4b4]
Tff7b72if Te6edf3own_hash Tff7b72is Tff7b72None Tff7b72or Te6edf3jh Tff7b72!= Te6edf3own_hashTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffnicksTb4b4b4[Te6edf3jhTb4b4b4] Tff7b72= Te6edf3joiner_nick

Tff7b72if Te6edf3self_joinTb4b4b4:
Tff7b72if Te6edf3silentTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_record_systemTb4b4b4(Te6edf3rTb4b4b4, Ta5d6ff"Ta5d6ffYou rejoined #Ta5d6ff" Tff7b72+ Te6edf3rTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_record_systemTb4b4b4(Te6edf3rTb4b4b4, Ta5d6ff"Ta5d6ffYou joined #Ta5d6ff" Tff7b72+ Te6edf3rTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffauto_whoTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_silent_who_roomsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsend_commandTb4b4b4(Ta5d6ff"Ta5d6ff/who Ta5d6ff" Tff7b72+ Te6edf3rTb4b4b4, Te6edf3roomTff7b72=Te6edf3rTb4b4b4, Te6edf3record_localTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_silent_who_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3joiner Tff7b72= Tff7b72None
Tff7b72if Tffa657lenTb4b4b4(Te6edf3body_hashesTb4b4b4) Tff7b72== T79c0ff1 Tff7b72and Tb4b4b4(
Te6edf3own_hash Tff7b72is Tff7b72None Tff7b72or Te6edf3body_hashesTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72!= Te6edf3own_hash
Tb4b4b4)Tb4b4b4:
Te6edf3joiner Tff7b72= Te6edf3body_hashesTb4b4b4[T79c0ff0Tb4b4b4]
Tff7b72if Te6edf3joiner Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_record_systemTb4b4b4(Te6edf3rTb4b4b4, Tff7b72selfTff7b72.Td2a8ffdisplay_name_forTb4b4b4(Te6edf3joinerTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff joinedTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ff_handle_partedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Te6edf3room Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_ROOMTb4b4b4)
Tff7b72if Tff7b72not Tb4b4b4(Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3r Tff7b72= Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Te6edf3body Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_BODYTb4b4b4)
Te6edf3parter_nick Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_NICKTb4b4b4)
Te6edf3own_hash Tff7b72= Tff7b72selfTff7b72.Td2a8ff_own_hashTb4b4b4(Tb4b4b4)

Te6edf3body_hashes Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3bodyTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Te6edf3body_hashes Tff7b72= Tb4b4b4[Tffa657bytesTb4b4b4(Te6edf3eTb4b4b4) Tff7b72for Te6edf3e Tff7b72in Te6edf3body Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3eTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4]

Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3self_part Tff7b72= Te6edf3r Tff7b72in Tff7b72selfTff7b72.Td2a8ff_pending_parts
Tff7b72if Te6edf3self_partTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_pending_partsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)

Tff7b72if Tb4b4b4(
Tb4b4b4(Tff7b72not Te6edf3self_partTb4b4b4)
Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3parter_nickTb4b4b4, Tffa657strTb4b4b4)
Tff7b72and Te6edf3parter_nick
Tff7b72and Tffa657lenTb4b4b4(Te6edf3body_hashesTb4b4b4) Tff7b72== T79c0ff1
Tb4b4b4)Tb4b4b4:
Te6edf3ph Tff7b72= Te6edf3body_hashesTb4b4b4[T79c0ff0Tb4b4b4]
Tff7b72if Te6edf3own_hash Tff7b72is Tff7b72None Tff7b72or Te6edf3ph Tff7b72!= Te6edf3own_hashTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffnicksTb4b4b4[Te6edf3phTb4b4b4] Tff7b72= Te6edf3parter_nick

Te6edf3members Tff7b72= Tff7b72selfTff7b72.Td2a8ffmembersTff7b72.Td2a8ffgetTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72if Te6edf3members Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72for Te6edf3h Tff7b72in Te6edf3body_hashesTb4b4b4:
Te6edf3membersTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3hTb4b4b4)
Tff7b72if Te6edf3self_partTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffroomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmembersTff7b72.Td2a8ffpopTb4b4b4(Te6edf3rTb4b4b4, Tff7b72NoneTb4b4b4)

Tff7b72if Te6edf3self_partTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3parter Tff7b72= Tff7b72None
Tff7b72if Tffa657lenTb4b4b4(Te6edf3body_hashesTb4b4b4) Tff7b72== T79c0ff1 Tff7b72and Tb4b4b4(
Te6edf3own_hash Tff7b72is Tff7b72None Tff7b72or Te6edf3body_hashesTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72!= Te6edf3own_hash
Tb4b4b4)Tb4b4b4:
Te6edf3parter Tff7b72= Te6edf3body_hashesTb4b4b4[T79c0ff0Tb4b4b4]
Tff7b72if Te6edf3parter Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_record_systemTb4b4b4(Te6edf3rTb4b4b4, Tff7b72selfTff7b72.Td2a8ffdisplay_name_forTb4b4b4(Te6edf3parterTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff leftTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ff_handle_chatTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4, Te6edf3kindTb4b4b4)Tb4b4b4:
Te6edf3body Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_BODYTb4b4b4)
Te6edf3room Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_ROOMTb4b4b4)
Te6edf3src Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_SRCTb4b4b4)
Te6edf3nick Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_NICKTb4b4b4)
Te6edf3mid Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_IDTb4b4b4)
Te6edf3own_hash Tff7b72= Tff7b72selfTff7b72.Td2a8ff_own_hashTb4b4b4(Tb4b4b4)
Te6edf3is_own Tff7b72= Tb4b4b4(
Tffa657isinstanceTb4b4b4(Te6edf3srcTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)
Tff7b72and Te6edf3own_hash Tff7b72is Tff7b72not Tff7b72None
Tff7b72and Tffa657bytesTb4b4b4(Te6edf3srcTb4b4b4) Tff7b72== Te6edf3own_hash
Tb4b4b4)
Tff7b72if Tb4b4b4(
Te6edf3is_own
Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3midTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)
Tff7b72and Tffa657bytesTb4b4b4(Te6edf3midTb4b4b4) Tff7b72in Tff7b72selfTff7b72.Td2a8ff_sent_ids
Tb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3srcTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4) Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3nickTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3nickTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffnicksTb4b4b4[Tffa657bytesTb4b4b4(Te6edf3srcTb4b4b4)Tb4b4b4] Tff7b72= Te6edf3nick
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3roomTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmembersTff7b72.Td2a8ffsetdefaultTb4b4b4(Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)Tb4b4b4, Tffa657setTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffaddTb4b4b4(Tffa657bytesTb4b4b4(Te6edf3srcTb4b4b4)Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3bodyTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3msg Tff7b72= Te6edf3protoTff7b72.Td2a8ffRRCMessageTb4b4b4(
Te6edf3kindTb4b4b4,
Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Tffa657bytesTb4b4b4(Te6edf3srcTb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3srcTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Te6edf3nick Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3nickTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Te6edf3bodyTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3is_own Tff7b72and Te6edf3protoTff7b72.Td2a8fftext_mentionsTb4b4b4(Te6edf3bodyTb4b4b4, Tff7b72selfTff7b72.Td2a8ffget_effective_nickTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3msgTff7b72.Td2a8ffmention Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_record_messageTb4b4b4(Te6edf3msgTb4b4b4)

Tff7b72def Td2a8ff_handle_msgTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_handle_chatTb4b4b4(Te6edf3envTb4b4b4, Ta5d6ff"Ta5d6ffmsgTa5d6ff"Tb4b4b4)

Tff7b72def Td2a8ff_handle_actionTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_handle_chatTb4b4b4(Te6edf3envTb4b4b4, Ta5d6ff"Ta5d6ffactionTa5d6ff"Tb4b4b4)

Tff7b72def Td2a8ff_handle_noticeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Te6edf3body Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_BODYTb4b4b4)
Te6edf3room Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_ROOMTb4b4b4)
Te6edf3src Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_SRCTb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3bodyTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72return

Te6edf3nick_prefix Tff7b72= Ta5d6ff"Ta5d6ffnickname set to Ta5d6ff"
Tff7b72if Te6edf3bodyTff7b72.Td2a8ffstartswithTb4b4b4(Te6edf3nick_prefixTb4b4b4)Tb4b4b4:
Te6edf3new_nick Tff7b72= Te6edf3bodyTb4b4b4[Tffa657lenTb4b4b4(Te6edf3nick_prefixTb4b4b4) Tb4b4b4:Tb4b4b4]Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3new_nickTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffset_nick_overrideTb4b4b4(Te6edf3new_nickTb4b4b4)

Te6edf3parsed Tff7b72= Te6edf3protoTff7b72.Td2a8ffparse_room_list_noticeTb4b4b4(Te6edf3bodyTb4b4b4)
Tff7b72if Te6edf3parsed Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffavailable_rooms Tff7b72= Te6edf3parsed
Te6edf3silent Tff7b72= Tff7b72selfTff7b72.Td2a8ff_silent_list_pending Tff7b72> T79c0ff0
Tff7b72if Te6edf3silentTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_silent_list_pending Tff7b72-Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72if Te6edf3silentTb4b4b4:
Tff7b72return

Te6edf3parsed_who Tff7b72= Te6edf3protoTff7b72.Td2a8ffparse_who_noticeTb4b4b4(Te6edf3bodyTb4b4b4)
Tff7b72if Te6edf3parsed_who Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3who_roomTb4b4b4, Te6edf3who_entries Tff7b72= Te6edf3parsed_who
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3members Tff7b72= Tff7b72selfTff7b72.Td2a8ffmembersTff7b72.Td2a8ffsetdefaultTb4b4b4(Te6edf3who_roomTb4b4b4, Tffa657setTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72for Te6edf3nickTb4b4b4, Te6edf3hash_hex Tff7b72in Te6edf3who_entriesTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3hash_bytes Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3hash_hexTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72continue
Tff7b72if Te6edf3nick Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3membersTff7b72.Td2a8ffaddTb4b4b4(Te6edf3hash_bytesTb4b4b4)
Tff7b72continue
Tff7b72for Te6edf3ph Tff7b72in Te6edf3membersTb4b4b4:
Tff7b72if Te6edf3phTff7b72.Td2a8ffstartswithTb4b4b4(Te6edf3hash_bytesTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffnicksTb4b4b4[Te6edf3phTb4b4b4] Tff7b72= Te6edf3nick
Tff7b72break
Te6edf3silent_who Tff7b72= Te6edf3who_room Tff7b72in Tff7b72selfTff7b72.Td2a8ff_silent_who_rooms
Tff7b72if Te6edf3silent_whoTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_silent_who_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3who_roomTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72if Te6edf3silent_whoTb4b4b4:
Tff7b72return

Te6edf3room_n Tff7b72= Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72None
Tff7b72if Te6edf3room_n Tff7b72is Tff7b72None Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3bodyTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3bodyTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmotd Tff7b72= Te6edf3body
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)
Te6edf3msg Tff7b72= Te6edf3protoTff7b72.Td2a8ffRRCMessageTb4b4b4(
Ta5d6ff"Ta5d6ffnoticeTa5d6ff"Tb4b4b4,
Te6edf3room_nTb4b4b4,
Tffa657bytesTb4b4b4(Te6edf3srcTb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3srcTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Tff7b72NoneTb4b4b4,
Te6edf3bodyTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_record_noticeTb4b4b4(Te6edf3msgTb4b4b4)

Tff7b72def Td2a8ff_handle_errorTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Te6edf3body Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_BODYTb4b4b4)
Te6edf3room Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_ROOMTb4b4b4)
Te6edf3text Tff7b72= Te6edf3body Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3bodyTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Ta5d6ff"Ta5d6ff(error)Ta5d6ff"
Te6edf3r Tff7b72= Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72None
Te6edf3rollback_join Tff7b72= Tff7b72False
Te6edf3forced_leave Tff7b72= Tff7b72False
Tff7b72if Te6edf3rTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Te6edf3r Tff7b72in Tff7b72selfTff7b72.Td2a8ff_pending_joinsTb4b4b4:
Te6edf3rollback_join Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_pending_joinsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_silent_joinsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_pending_partsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72if Te6edf3rollback_joinTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffroomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmention_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_countsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3rTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72elif Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffis_forced_leave_errorTb4b4b4(Te6edf3textTb4b4b4) Tff7b72and Te6edf3r Tff7b72in Tff7b72selfTff7b72.Td2a8ffroomsTb4b4b4:
Te6edf3forced_leave Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffroomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmembersTff7b72.Td2a8ffpopTb4b4b4(Te6edf3rTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmention_roomsTff7b72.Td2a8ffdiscardTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffunread_countsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3rTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72if Te6edf3rollback_join Tff7b72or Te6edf3forced_leaveTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
T8b949e# Drop a remembered key that the hub rejected so reconnect does not loop.
Tff7b72if Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffis_bad_key_errorTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ffforget_room_keyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3rTb4b4b4)
Te6edf3msg Tff7b72= Te6edf3protoTff7b72.Td2a8ffRRCMessageTb4b4b4(Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4, Te6edf3rTb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4, Te6edf3textTb4b4b4, Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_record_noticeTb4b4b4(Te6edf3msgTb4b4b4)

Tff7b72def Td2a8ff_handle_resource_envelopeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3envTb4b4b4)Tb4b4b4:
Te6edf3body Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_BODYTb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3bodyTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3rid Tff7b72= Te6edf3bodyTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffB_RES_IDTb4b4b4)
Te6edf3kind Tff7b72= Te6edf3bodyTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffB_RES_KINDTb4b4b4)
Te6edf3size Tff7b72= Te6edf3bodyTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffB_RES_SIZETb4b4b4)
Te6edf3sha256 Tff7b72= Te6edf3bodyTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffB_RES_SHA256Tb4b4b4)
Te6edf3encoding Tff7b72= Te6edf3bodyTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffB_RES_ENCODINGTb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3ridTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3kindTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3sizeTb4b4b4, Tffa657intTb4b4b4) Tff7b72or Te6edf3size Tff7b72<Tff7b72= T79c0ff0Tb4b4b4:
Tff7b72return
Te6edf3room Tff7b72= Te6edf3envTff7b72.Td2a8ffgetTb4b4b4(Te6edf3protoTff7b72.Td2a8ffK_ROOMTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_resource_expectationsTb4b4b4[Tffa657bytesTb4b4b4(Te6edf3ridTb4b4b4)Tb4b4b4] Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffkindTa5d6ff"Tb4b4b4: Te6edf3kindTb4b4b4,
Ta5d6ff"Ta5d6ffsizeTa5d6ff"Tb4b4b4: Te6edf3sizeTb4b4b4,
Ta5d6ff"Ta5d6ffsha256Ta5d6ff"Tb4b4b4: Tffa657bytesTb4b4b4(Te6edf3sha256Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3sha256Tb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)
Tff7b72else Tff7b72NoneTb4b4b4,
Ta5d6ff"Ta5d6ffencodingTa5d6ff"Tb4b4b4: Te6edf3encoding Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3encodingTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4: Te6edf3roomTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3roomTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Ta5d6ff"Ta5d6ffexpiresTa5d6ff"Tb4b4b4: Te6edf3timeTff7b72.Td2a8ffmonotonicTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff30.0Tb4b4b4,
Tb4b4b4}

Te6edf3_PACKET_HANDLERS Tff7b72= Tb4b4b4{
Te6edf3protoTff7b72.Td2a8ffT_PINGTb4b4b4: Te6edf3_handle_pingTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffT_PONGTb4b4b4: Te6edf3_handle_pongTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffT_WELCOMETb4b4b4: Te6edf3_handle_welcomeTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffT_JOINEDTb4b4b4: Te6edf3_handle_joinedTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffT_PARTEDTb4b4b4: Te6edf3_handle_partedTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffT_MSGTb4b4b4: Te6edf3_handle_msgTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffT_ACTIONTb4b4b4: Te6edf3_handle_actionTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffT_NOTICETb4b4b4: Te6edf3_handle_noticeTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffT_ERRORTb4b4b4: Te6edf3_handle_errorTb4b4b4,
Te6edf3protoTff7b72.Td2a8ffT_RESOURCE_ENVELOPETb4b4b4: Te6edf3_handle_resource_envelopeTb4b4b4,
Tb4b4b4}

Tff7b72def Td2a8ff_resource_advertisedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3resourceTb4b4b4, Ta5d6ff"Ta5d6ffget_data_sizeTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3size Tff7b72= Te6edf3resourceTff7b72.Td2a8ffget_data_sizeTb4b4b4(Tb4b4b4)
Tff7b72elif Tffa657hasattrTb4b4b4(Te6edf3resourceTb4b4b4, Ta5d6ff"Ta5d6fftotal_sizeTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3size Tff7b72= Te6edf3resourceTff7b72.Td2a8fftotal_size
Tff7b72elseTb4b4b4:
Te6edf3size Tff7b72= Tffa657getattrTb4b4b4(Te6edf3resourceTb4b4b4, Ta5d6ff"Ta5d6ffsizeTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72False
Tff7b72return Te6edf3size Tff7b72<Tff7b72= T79c0ff262144

Tff7b72def Td2a8ff_resource_concludedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3resourceTff7b72.Td2a8ffstatus Tff7b72!= Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffCOMPLETETb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3resourceTb4b4b4, Ta5d6ff"Ta5d6ffdataTa5d6ff"Tb4b4b4) Tff7b72and Te6edf3resourceTff7b72.Td2a8ffdataTb4b4b4:
Te6edf3resourceTff7b72.Td2a8ffdataTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72return
Te6edf3data Tff7b72= Tff7b72None
Tff7b72tryTb4b4b4:
Te6edf3data Tff7b72= Te6edf3resourceTff7b72.Td2a8ffdataTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Tff7b72finallyTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3resourceTb4b4b4, Ta5d6ff"Ta5d6ffdataTa5d6ff"Tb4b4b4) Tff7b72and Te6edf3resourceTff7b72.Td2a8ffdataTb4b4b4:
Te6edf3resourceTff7b72.Td2a8ffdataTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3data Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return

Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8ffmonotonicTb4b4b4(Tb4b4b4)
Te6edf3matched Tff7b72= Tff7b72None
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3expired Tff7b72= Tb4b4b4[
Te6edf3k
Tff7b72for Te6edf3kTb4b4b4, Te6edf3v Tff7b72in Tff7b72selfTff7b72.Td2a8ff_resource_expectationsTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3vTb4b4b4[Ta5d6ff"Ta5d6ffexpiresTa5d6ff"Tb4b4b4] Tff7b72< Te6edf3now
Tb4b4b4]
Tff7b72for Te6edf3k Tff7b72in Te6edf3expiredTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_resource_expectationsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3kTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72for Te6edf3kTb4b4b4, Te6edf3exp Tff7b72in Tffa657listTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_resource_expectationsTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3expTb4b4b4[Ta5d6ff"Ta5d6ffsizeTa5d6ff"Tb4b4b4] Tff7b72== Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Te6edf3matched Tff7b72= Te6edf3exp
Tff7b72selfTff7b72.Td2a8ff_resource_expectationsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3kTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72break

Te6edf3kind Tff7b72= Te6edf3matchedTb4b4b4[Ta5d6ff"Ta5d6ffkindTa5d6ff"Tb4b4b4] Tff7b72if Te6edf3matched Tff7b72else Te6edf3protoTff7b72.Td2a8ffRES_KIND_BLOB
Te6edf3room Tff7b72= Te6edf3matchedTb4b4b4[Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4] Tff7b72if Te6edf3matched Tff7b72else Tff7b72None
Te6edf3encoding Tff7b72= Te6edf3matchedTb4b4b4[Ta5d6ff"Ta5d6ffencodingTa5d6ff"Tb4b4b4] Tff7b72if Te6edf3matched Tff7b72else Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"
Te6edf3sha Tff7b72= Te6edf3matchedTb4b4b4[Ta5d6ff"Ta5d6ffsha256Ta5d6ff"Tb4b4b4] Tff7b72if Te6edf3matched Tff7b72else Tff7b72None
Tff7b72if Te6edf3sha Tff7b72is Tff7b72not Tff7b72None Tff7b72and Te6edf3hashlibTff7b72.Td2a8ffsha256Tb4b4b4(Te6edf3dataTb4b4b4)Tff7b72.Td2a8ffdigestTb4b4b4(Tb4b4b4) Tff7b72!= Te6edf3shaTb4b4b4:
Tff7b72return
Tff7b72if Te6edf3kind Tff7b72in Tb4b4b4(Te6edf3protoTff7b72.Td2a8ffRES_KIND_NOTICETb4b4b4, Te6edf3protoTff7b72.Td2a8ffRES_KIND_MOTDTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3text Tff7b72= Te6edf3dataTff7b72.Td2a8ffdecodeTb4b4b4(Te6edf3encodingTb4b4b4, Te6edf3errorsTff7b72=Ta5d6ff"Ta5d6ffreplaceTa5d6ff"Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return
Tff7b72if Te6edf3kind Tff7b72== Te6edf3protoTff7b72.Td2a8ffRES_KIND_MOTDTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmotd Tff7b72= Te6edf3text
Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4)
Te6edf3msg Tff7b72= Te6edf3protoTff7b72.Td2a8ffRRCMessageTb4b4b4(Ta5d6ff"Ta5d6ffnoticeTa5d6ff"Tb4b4b4, Te6edf3roomTb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4, Te6edf3textTb4b4b4, Te6edf3protoTff7b72.Td2a8ffnow_msTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_record_noticeTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_logTb4b4b4(Ta5d6ff"Ta5d6ffresource handling failed: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72def Td2a8ffto_dictTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Return a JSON-serializable summary of this hub's state."""
Te6edf3stored_key_rooms Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3stored_key_rooms Tff7b72= Tb4b4b4[
Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4] Tff7b72for Te6edf3entry Tff7b72in Tff7b72selfTff7b72.Td2a8ffmanagerTff7b72.Td2a8fflist_stored_room_keysTb4b4b4(Tff7b72selfTb4b4b4)
Tb4b4b4]
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3rooms Tff7b72= Tffa657sortedTb4b4b4(Tff7b72selfTff7b72.Td2a8ffroomsTb4b4b4)
Te6edf3known_rooms Tff7b72= Tff7b72selfTff7b72.Td2a8ffordered_known_roomsTb4b4b4(Tb4b4b4)
Te6edf3unread_counts Tff7b72= Tb4b4b4{Te6edf3kTb4b4b4: Te6edf3v Tff7b72for Te6edf3kTb4b4b4, Te6edf3v Tff7b72in Tff7b72selfTff7b72.Td2a8ffunread_countsTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4) Tff7b72if Te6edf3v Tff7b72> T79c0ff0Tb4b4b4}
Te6edf3total_unread Tff7b72= Tffa657sumTb4b4b4(Te6edf3unread_countsTff7b72.Td2a8ffvaluesTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffhub_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffdest_nameTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffdest_nameTb4b4b4,
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffnameTb4b4b4,
Ta5d6ff"Ta5d6ffdisplay_nameTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffget_display_nameTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffcustom_nameTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffcustom_nameTb4b4b4,
Ta5d6ff"Ta5d6ffhub_iconTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffget_hub_iconTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffhub_name_announcedTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffhub_nameTb4b4b4,
Ta5d6ff"Ta5d6ffstatusTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffstatusTb4b4b4,
Ta5d6ff"Ta5d6ffstatus_textTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffstatus_textTb4b4b4,
Ta5d6ff"Ta5d6ffconnectedTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_CONNECTEDTb4b4b4,
Ta5d6ff"Ta5d6ffhub_nameTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffhub_nameTb4b4b4,
Ta5d6ff"Ta5d6ffhub_versionTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffhub_versionTb4b4b4,
Ta5d6ff"Ta5d6ffmotdTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffmotdTb4b4b4,
Ta5d6ff"Ta5d6ffroomsTa5d6ff"Tb4b4b4: Te6edf3roomsTb4b4b4,
Ta5d6ff"Ta5d6ffknown_roomsTa5d6ff"Tb4b4b4: Te6edf3known_roomsTb4b4b4,
Ta5d6ff"Ta5d6ffunread_roomsTa5d6ff"Tb4b4b4: Tffa657sortedTb4b4b4(Tff7b72selfTff7b72.Td2a8ffunread_roomsTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffunread_countsTa5d6ff"Tb4b4b4: Te6edf3unread_countsTb4b4b4,
Ta5d6ff"Ta5d6fftotal_unreadTa5d6ff"Tb4b4b4: Te6edf3total_unreadTb4b4b4,
Ta5d6ff"Ta5d6ffmention_roomsTa5d6ff"Tb4b4b4: Tffa657sortedTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmention_roomsTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffavailable_roomsTa5d6ff"Tb4b4b4: Tffa657dictTb4b4b4(Tff7b72selfTff7b72.Td2a8ffavailable_roomsTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffstored_key_roomsTa5d6ff"Tb4b4b4: Te6edf3stored_key_roomsTb4b4b4,
Ta5d6ff"Ta5d6ffauto_reconnectTa5d6ff"Tb4b4b4: Tffa657boolTb4b4b4(Tff7b72selfTff7b72.Td2a8ffauto_reconnectTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffauto_listTa5d6ff"Tb4b4b4: Tffa657boolTb4b4b4(Tff7b72selfTff7b72.Td2a8ffauto_listTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffauto_whoTa5d6ff"Tb4b4b4: Tffa657boolTb4b4b4(Tff7b72selfTff7b72.Td2a8ffauto_whoTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffnick_overrideTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffnick_overrideTb4b4b4,
Ta5d6ff"Ta5d6ffmax_msg_body_bytesTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffmax_msg_body_bytesTb4b4b4,
Tb4b4b4}

Tff7b72def Td2a8ffroom_messagesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4, Te6edf3limitTff7b72=Tff7b72NoneTb4b4b4, Te6edf3before_seqTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
T8b949e"""Return (messages, has_more) for a room, newest page last.

before_seq, when given, restricts results to messages recorded
before that sequence number, letting callers page backwards through
history. limit caps how many of the most recent matching messages
are returned; has_more reports whether older messages remain.
"""
Te6edf3msgs Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_messagesTb4b4b4(Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3before_seq Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3msgs Tff7b72= Tb4b4b4[Te6edf3m Tff7b72for Te6edf3m Tff7b72in Te6edf3msgs Tff7b72if Tb4b4b4(Te6edf3mTff7b72.Td2a8ffseq Tff7b72or T79c0ff0Tb4b4b4) Tff7b72< Te6edf3before_seqTb4b4b4]
Te6edf3has_more Tff7b72= Tff7b72False
Tff7b72if Te6edf3limit Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3msgsTb4b4b4) Tff7b72> Te6edf3limitTb4b4b4:
Te6edf3has_more Tff7b72= Tff7b72True
Te6edf3msgs Tff7b72= Te6edf3msgsTb4b4b4[Tff7b72-Te6edf3limitTb4b4b4:Tb4b4b4]
Tff7b72return Tb4b4b4[Te6edf3mTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4) Tff7b72for Te6edf3m Tff7b72in Te6edf3msgsTb4b4b4]Tb4b4b4, Te6edf3has_more

Tff7b72def Td2a8ffmembers_dictTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
T8b949e"""Return serialized members for a room."""
Te6edf3r Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Te6edf3out Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3h Tff7b72in Tff7b72selfTff7b72.Td2a8ffget_membersTb4b4b4(Te6edf3rTb4b4b4)Tb4b4b4:
Te6edf3outTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4: Te6edf3hTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffdisplay_name_forTb4b4b4(Te6edf3hTb4b4b4)Tb4b4b4}Tb4b4b4)
Te6edf3outTff7b72.Td2a8ffsortTb4b4b4(Te6edf3keyTff7b72=Tff7b72lambda Te6edf3mTb4b4b4: Te6edf3mTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4]Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3out


Tff7b72class T56d364RRCManagerTb4b4b4:
T8b949e"""Owns the set of configured RRC hubs and relays their events."""

Tff7b72def Tff7b72__init__Tb4b4b4(
Tff7b72selfTb4b4b4,
Te6edf3identityTb4b4b4,
Te6edf3storage_dirTb4b4b4,
Te6edf3get_nicknameTff7b72=Tff7b72NoneTb4b4b4,
Te6edf3get_name_for_identity_hashTff7b72=Tff7b72NoneTb4b4b4,
Te6edf3history_per_room_capTff7b72=T79c0ff0Tb4b4b4,
Te6edf3filter_loaded_historyTff7b72=Tff7b72TrueTb4b4b4,
Te6edf3ephemeral_noticesTff7b72=Te6edf3RRCHubTff7b72.Td2a8ffSYS_NOTICE_TIMEOUTTb4b4b4,
Te6edf3databaseTff7b72=Tff7b72NoneTb4b4b4,
Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffidentity Tff7b72= Te6edf3identity
Tff7b72selfTff7b72.Td2a8ffstorage_dir Tff7b72= Te6edf3storage_dir
Tff7b72selfTff7b72.Td2a8ff_get_nickname Tff7b72= Te6edf3get_nickname
Tff7b72selfTff7b72.Td2a8ffget_name_for_identity_hash Tff7b72= Te6edf3get_name_for_identity_hash
Tff7b72selfTff7b72.Td2a8ffhistory_per_room_cap Tff7b72= Te6edf3history_per_room_cap
Tff7b72selfTff7b72.Td2a8fffilter_loaded_history Tff7b72= Te6edf3filter_loaded_history
Tff7b72selfTff7b72.Td2a8ffephemeral_notices Tff7b72= Te6edf3ephemeral_notices
Tff7b72selfTff7b72.Td2a8ffdatabase Tff7b72= Te6edf3database

Tff7b72selfTff7b72.Td2a8ffhubs Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ff_server_manager Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_lock Tff7b72= Te6edf3threadingTff7b72.Td2a8ffRLockTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_change_callback Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_message_callback Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_active_hub Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_active_room Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_loaded Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_loading Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_save_lock Tff7b72= Te6edf3threadingTff7b72.Td2a8ffLockTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffset_databaseTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3databaseTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdatabase Tff7b72= Te6edf3database

Tff7b72def Td2a8ff_private_key_bytesTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3identity Tff7b72= Tff7b72selfTff7b72.Td2a8ffidentity
Tff7b72if Te6edf3identity Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3key Tff7b72= Te6edf3identityTff7b72.Td2a8ffget_private_keyTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3keyTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4) Tff7b72and Te6edf3keyTb4b4b4:
Tff7b72return Tffa657bytesTb4b4b4(Te6edf3keyTb4b4b4)
Tff7b72return Tff7b72None

Tff7b72def Td2a8ff_room_key_daoTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3db Tff7b72= Tff7b72selfTff7b72.Td2a8ffdatabase
Tff7b72if Te6edf3db Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72return Tffa657getattrTb4b4b4(Te6edf3dbTb4b4b4, Ta5d6ff"Ta5d6ffrrc_room_keysTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)

Tf0883e@staticmethod
Tff7b72def Td2a8ff_hub_hash_hexTb4b4b4(Te6edf3hub_or_hashTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3hub_or_hashTb4b4b4, Te6edf3RRCHubTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3hub_or_hashTff7b72.Td2a8ffhub_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3hub_or_hashTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72return Tffa657bytesTb4b4b4(Te6edf3hub_or_hashTb4b4b4)Tff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3hub_or_hashTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3hub_or_hashTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffinvalid hub hashTa5d6ff"
Tff7b72raise Tf85149TypeErrorTb4b4b4(Te6edf3msgTb4b4b4)

Tf0883e@staticmethod
Tff7b72def Td2a8ff_dest_name_forTb4b4b4(Te6edf3hub_or_destTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3hub_or_destTb4b4b4, Te6edf3RRCHubTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3hub_or_destTff7b72.Td2a8ffdest_name Tff7b72or Te6edf3DEFAULT_DEST_NAME
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3hub_or_destTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3hub_or_destTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3hub_or_destTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3DEFAULT_DEST_NAME

Tff7b72def Td2a8ffremember_room_keyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4, Te6edf3keyTb4b4b4)Tb4b4b4:
T8b949e"""Encrypt and persist a room key for later joins."""
Te6edf3dao Tff7b72= Tff7b72selfTff7b72.Td2a8ff_room_key_daoTb4b4b4(Tb4b4b4)
Te6edf3private_key Tff7b72= Tff7b72selfTff7b72.Td2a8ff_private_key_bytesTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3dao Tff7b72is Tff7b72None Tff7b72or Te6edf3private_key Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffroom key storage is unavailableTa5d6ff"
Tff7b72raise Tf85149RuntimeErrorTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3room_n Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Te6edf3nonceTb4b4b4, Te6edf3ciphertext Tff7b72= Te6edf3encrypt_room_keyTb4b4b4(Te6edf3private_keyTb4b4b4, Te6edf3keyTb4b4b4)
Te6edf3daoTff7b72.Td2a8ffupsertTb4b4b4(
Tff7b72selfTff7b72.Td2a8ff_hub_hash_hexTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ff_dest_name_forTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Te6edf3room_nTb4b4b4,
Te6edf3nonceTb4b4b4,
Te6edf3ciphertextTb4b4b4,
Tb4b4b4)

Tff7b72def Td2a8ffforget_room_keyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Te6edf3dao Tff7b72= Tff7b72selfTff7b72.Td2a8ff_room_key_daoTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3dao Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return T79c0ff0
Te6edf3room_n Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Tff7b72return Te6edf3daoTff7b72.Td2a8ffdeleteTb4b4b4(
Tff7b72selfTff7b72.Td2a8ff_hub_hash_hexTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ff_dest_name_forTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Te6edf3room_nTb4b4b4,
Tb4b4b4)

Tff7b72def Td2a8ffget_room_keyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
T8b949e"""Return the decrypted room key, or None when missing or undecryptable."""
Te6edf3dao Tff7b72= Tff7b72selfTff7b72.Td2a8ff_room_key_daoTb4b4b4(Tb4b4b4)
Te6edf3private_key Tff7b72= Tff7b72selfTff7b72.Td2a8ff_private_key_bytesTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3dao Tff7b72is Tff7b72None Tff7b72or Te6edf3private_key Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72None
Te6edf3room_n Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Te6edf3row Tff7b72= Te6edf3daoTff7b72.Td2a8ffgetTb4b4b4(
Tff7b72selfTff7b72.Td2a8ff_hub_hash_hexTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ff_dest_name_forTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Te6edf3room_nTb4b4b4,
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3rowTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72tryTb4b4b4:
Tff7b72return Te6edf3decrypt_room_keyTb4b4b4(Te6edf3private_keyTb4b4b4, Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffnonceTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffciphertextTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffhas_stored_room_keyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Te6edf3dao Tff7b72= Tff7b72selfTff7b72.Td2a8ff_room_key_daoTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3dao Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72False
Te6edf3room_n Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3roomTb4b4b4)
Te6edf3row Tff7b72= Te6edf3daoTff7b72.Td2a8ffgetTb4b4b4(
Tff7b72selfTff7b72.Td2a8ff_hub_hash_hexTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ff_dest_name_forTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Te6edf3room_nTb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3row Tff7b72is Tff7b72not Tff7b72None

Tff7b72def Td2a8fflist_stored_room_keysTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4)Tb4b4b4:
Te6edf3dao Tff7b72= Tff7b72selfTff7b72.Td2a8ff_room_key_daoTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3dao Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tb4b4b4[Tb4b4b4]
Te6edf3rows Tff7b72= Te6edf3daoTff7b72.Td2a8fflist_for_hubTb4b4b4(
Tff7b72selfTff7b72.Td2a8ff_hub_hash_hexTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ff_dest_name_forTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72return Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4: Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffhub_hashTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffdest_nameTa5d6ff"Tb4b4b4: Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffdest_nameTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4: Te6edf3rowTb4b4b4[Ta5d6ff"Ta5d6ffroomTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffupdated_atTa5d6ff"Tb4b4b4: Te6edf3rowTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffupdated_atTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4}
Tff7b72for Te6edf3row Tff7b72in Te6edf3rows Tff7b72or Tb4b4b4[Tb4b4b4]
Tb4b4b4]

Tf0883e@staticmethod
Tff7b72def Td2a8ffis_bad_key_errorTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3textTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Te6edf3lowered Tff7b72= Te6edf3textTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
T8b949e# Require the words "bad key" so mode hints like "enable +k" do not wipe storage.
Tff7b72return Tffa657anyTb4b4b4(Te6edf3marker Tff7b72in Te6edf3lowered Tff7b72for Te6edf3marker Tff7b72in Te6edf3BAD_KEY_MARKERSTb4b4b4)

Tf0883e@staticmethod
Tff7b72def Td2a8ffis_forced_leave_errorTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3textTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Te6edf3lowered Tff7b72= Te6edf3textTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Tff7b72return Tffa657anyTb4b4b4(Te6edf3marker Tff7b72in Te6edf3lowered Tff7b72for Te6edf3marker Tff7b72in Te6edf3FORCED_LEAVE_MARKERSTb4b4b4)

Tff7b72def Td2a8ffget_nicknameTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_get_nickname Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72tryTb4b4b4:
Te6edf3n Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_nicknameTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72return Te6edf3n Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3nTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3n Tff7b72else Tff7b72None

Tff7b72def Td2a8ffset_server_managerTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3server_managerTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_server_manager Tff7b72= Te6edf3server_manager

Tff7b72def Td2a8fffind_local_serverTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hub_hashTb4b4b4)Tb4b4b4:
T8b949e"""Return a running locally hosted hub matching hub_hash, if any."""
Te6edf3sm Tff7b72= Tff7b72selfTff7b72.Td2a8ff_server_manager
Tff7b72if Te6edf3sm Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3hub Tff7b72in Tffa657listTb4b4b4(Te6edf3smTff7b72.Td2a8ffhubsTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3hubTff7b72.Td2a8ffrunning Tff7b72and Te6edf3hubTff7b72.Td2a8ffdest_hash Tff7b72== Te6edf3hub_hashTb4b4b4:
Tff7b72return Te6edf3hub
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffset_change_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3cbTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_change_callback Tff7b72= Te6edf3cb

Tff7b72def Td2a8ffset_message_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3cbTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_message_callback Tff7b72= Te6edf3cb

Tff7b72def Td2a8ff_notify_changeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_change_callback Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_change_callbackTb4b4b4(Te6edf3hubTb4b4b4)

Tff7b72def Td2a8ff_notify_messagesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3msgTb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_message_callback Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_message_callbackTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3msgTb4b4b4)

Tff7b72def Td2a8ff_on_welcomeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3r Tff7b72in Tffa657listTb4b4b4(Te6edf3hubTff7b72.Td2a8ffroomsTb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3key Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_room_keyTb4b4b4(Te6edf3hubTb4b4b4, Te6edf3rTb4b4b4)
Te6edf3hubTff7b72.Td2a8ffjoin_roomTb4b4b4(Te6edf3rTb4b4b4, Te6edf3keyTff7b72=Te6edf3keyTb4b4b4, Te6edf3silentTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72def Td2a8ffset_activeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_active_hub Tff7b72= Te6edf3hub
Tff7b72selfTff7b72.Td2a8ff_active_room Tff7b72= Te6edf3room
Tff7b72if Te6edf3hub Tff7b72is Tff7b72not Tff7b72None Tff7b72and Te6edf3room Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffmark_readTb4b4b4(Te6edf3roomTb4b4b4)

Tff7b72def Td2a8ffactive_room_forTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_active_hub Tff7b72is Te6edf3hubTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_active_room
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffhas_unreadTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72return Tffa657anyTb4b4b4(Te6edf3hubTff7b72.Td2a8ffunread_rooms Tff7b72for Te6edf3hub Tff7b72in Tff7b72selfTff7b72.Td2a8ffhubsTb4b4b4)

Tff7b72def Td2a8ffadd_hubTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hub_hashTb4b4b4, Te6edf3dest_nameTff7b72=Tff7b72NoneTb4b4b4, Te6edf3nameTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72for Te6edf3h Tff7b72in Tff7b72selfTff7b72.Td2a8ffhubsTb4b4b4:
Tff7b72if Te6edf3hTff7b72.Td2a8ffhub_hash Tff7b72== Te6edf3hub_hash Tff7b72and Te6edf3hTff7b72.Td2a8ffdest_name Tff7b72== Tb4b4b4(
Te6edf3dest_name Tff7b72or Te6edf3protoTff7b72.Td2a8ffDEFAULT_DEST_NAME
Tb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3h
Te6edf3hub Tff7b72= Te6edf3RRCHubTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hub_hashTb4b4b4, Te6edf3dest_nameTff7b72=Te6edf3dest_nameTb4b4b4, Te6edf3nameTff7b72=Te6edf3nameTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhubsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3hubTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_notify_changeTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3hub

Tff7b72def Td2a8ffremove_hubTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Te6edf3hub Tff7b72in Tff7b72selfTff7b72.Td2a8ffhubsTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhubsTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3hubTb4b4b4)
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffdisconnectTb4b4b4(Tb4b4b4)
Te6edf3dao Tff7b72= Tff7b72selfTff7b72.Td2a8ff_room_key_daoTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3dao Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3daoTff7b72.Td2a8ffdelete_for_hubTb4b4b4(
Tff7b72selfTff7b72.Td2a8ff_hub_hash_hexTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ff_dest_name_forTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_notify_changeTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8fffind_hubTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hub_hashTb4b4b4, Te6edf3dest_nameTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Te6edf3dn Tff7b72= Te6edf3dest_name Tff7b72or Te6edf3protoTff7b72.Td2a8ffDEFAULT_DEST_NAME
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72for Te6edf3h Tff7b72in Tff7b72selfTff7b72.Td2a8ffhubsTb4b4b4:
Tff7b72if Te6edf3hTff7b72.Td2a8ffhub_hash Tff7b72== Te6edf3hub_hash Tff7b72and Te6edf3hTff7b72.Td2a8ffdest_name Tff7b72== Te6edf3dnTb4b4b4:
Tff7b72return Te6edf3h
Tff7b72return Tff7b72None

Tff7b72def Td2a8fffind_hub_by_hexTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hub_hash_hexTb4b4b4, Te6edf3dest_nameTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3hub_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3hub_hash_hexTb4b4b4)
Tff7b72except Tb4b4b4(Tf85149ValueErrorTb4b4b4, Tf85149TypeErrorTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72None
Tff7b72if Te6edf3dest_name Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8fffind_hubTb4b4b4(Te6edf3hub_hashTb4b4b4, Te6edf3dest_nameTff7b72=Te6edf3dest_nameTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72for Te6edf3h Tff7b72in Tff7b72selfTff7b72.Td2a8ffhubsTb4b4b4:
Tff7b72if Te6edf3hTff7b72.Td2a8ffhub_hash Tff7b72== Te6edf3hub_hashTb4b4b4:
Tff7b72return Te6edf3h
Tff7b72return Tff7b72None

Tff7b72def Td2a8ff_store_pathTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_dirTb4b4b4, Ta5d6ff"Ta5d6ffrrc_hubsTa5d6ff"Tb4b4b4)

Tff7b72def Td2a8ff_history_rootTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstorage_dirTb4b4b4, Te6edf3HISTORY_DIR_NAMETb4b4b4)

Tff7b72def Td2a8ff_history_dirTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4)Tb4b4b4:
Te6edf3hub_key Tff7b72= Te6edf3hubTff7b72.Td2a8ffhub_hashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3hubTff7b72.Td2a8ffdest_name Tff7b72and Te6edf3hubTff7b72.Td2a8ffdest_name Tff7b72!= Te6edf3protoTff7b72.Td2a8ffDEFAULT_DEST_NAMETb4b4b4:
Te6edf3suffix Tff7b72= Te6edf3hashlibTff7b72.Td2a8ffsha256Tb4b4b4(Te6edf3hubTff7b72.Td2a8ffdest_nameTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffhexdigestTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4]
Te6edf3hub_key Tff7b72= Te6edf3hub_key Tff7b72+ Ta5d6ff"Ta5d6ff__Ta5d6ff" Tff7b72+ Te6edf3suffix
Tff7b72return Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_history_rootTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3hub_keyTb4b4b4)

Tff7b72def Td2a8ff_history_pathTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4, Te6edf3roomTb4b4b4)Tb4b4b4:
Te6edf3sanitized Tff7b72= Te6edf3HISTORY_FILENAME_SANITIZE_RETff7b72.Td2a8ffsubTb4b4b4(Ta5d6ff"Ta5d6ff_Ta5d6ff"Tb4b4b4, Te6edf3room Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff64Tb4b4b4]
Te6edf3room_hash Tff7b72= Te6edf3hashlibTff7b72.Td2a8ffsha256Tb4b4b4(Tb4b4b4(Te6edf3room Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffhexdigestTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4]
Tff7b72if Te6edf3sanitizedTb4b4b4:
Te6edf3filename Tff7b72= Te6edf3sanitized Tff7b72+ Ta5d6ff"Ta5d6ff_Ta5d6ff" Tff7b72+ Te6edf3room_hash Tff7b72+ Ta5d6ff"Ta5d6ff.logTa5d6ff"
Tff7b72elseTb4b4b4:
Te6edf3filename Tff7b72= Te6edf3room_hash Tff7b72+ Ta5d6ff"Ta5d6ff.logTa5d6ff"
Tff7b72return Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_history_dirTb4b4b4(Te6edf3hubTb4b4b4)Tb4b4b4, Te6edf3filenameTb4b4b4)

Tff7b72def Td2a8ff_ensure_history_dirTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hubTb4b4b4)Tb4b4b4:
Te6edf3d Tff7b72= Tff7b72selfTff7b72.Td2a8ff_history_dirTb4b4b4(Te6edf3hubTb4b4b4)
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Te6edf3dTb4b4b4, Te6edf3exist_okTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72return Te6edf3d

Tff7b72def Td2a8ffloadTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_loadedTb4b4b4:
Tff7b72return
Tff7b72selfTff7b72.Td2a8ff_loaded Tff7b72= Tff7b72True
Te6edf3path Tff7b72= Tff7b72selfTff7b72.Td2a8ff_store_pathTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72selfTff7b72.Td2a8ff_loading Tff7b72= Tff7b72True
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3data Tff7b72= Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Te6edf3obj Tff7b72= Te6edf3protoTff7b72.Td2a8ffdecodeTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3objTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3entries Tff7b72= Te6edf3objTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhubsTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3entriesTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72for Te6edf3e Tff7b72in Te6edf3entriesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_load_hub_entryTb4b4b4(Te6edf3eTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffFailed to load RRC hubs: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72finallyTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_loading Tff7b72= Tff7b72False

Tff7b72def Td2a8ffconnect_auto_reconnect_hubsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Connect hubs that have auto-reconnect enabled (e.g. after startup load)."""
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3hubs Tff7b72= Tb4b4b4[Te6edf3h Tff7b72for Te6edf3h Tff7b72in Tff7b72selfTff7b72.Td2a8ffhubs Tff7b72if Te6edf3hTff7b72.Td2a8ffauto_reconnectTb4b4b4]
Tff7b72for Te6edf3hub Tff7b72in Te6edf3hubsTb4b4b4:
Tff7b72with Te6edf3hubTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72if Te6edf3hubTff7b72.Td2a8ffstatus Tff7b72in Tb4b4b4(
Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_CONNECTINGTb4b4b4,
Te6edf3RRCHubTff7b72.Td2a8ffSTATUS_CONNECTEDTb4b4b4,
Tb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3hubTff7b72.Td2a8ffconnectTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff_load_hub_entryTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3eTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3eTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3hh Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3hhTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3dn Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffdest_nameTa5d6ff"Tb4b4b4)
Te6edf3nm Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4)
Te6edf3hub Tff7b72= Tff7b72selfTff7b72.Td2a8ffadd_hubTb4b4b4(
Tffa657bytesTb4b4b4(Te6edf3hhTb4b4b4)Tb4b4b4,
Te6edf3dest_nameTff7b72=Te6edf3dn Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3dnTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Te6edf3nameTff7b72=Te6edf3nm Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3nmTb4b4b4, Tffa657strTb4b4b4) Tff7b72else Tff7b72NoneTb4b4b4,
Tb4b4b4)
Te6edf3rooms Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroomsTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3roomsTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3r Tff7b72in Te6edf3roomsTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3rTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffadd_roomTb4b4b4(Te6edf3rTb4b4b4)
Te6edf3parted Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffparted_roomsTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3partedTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3r Tff7b72in Te6edf3partedTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3rTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3rn Tff7b72= Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3rTb4b4b4)
Tff7b72with Te6edf3hubTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffsetdefaultTb4b4b4(Te6edf3rnTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)
Te6edf3cn Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcustom_nameTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3cnTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3cnTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffcustom_name Tff7b72= Te6edf3cnTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Te6edf3hi Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhub_iconTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3hiTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3hiTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffset_hub_iconTb4b4b4(Te6edf3hiTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3saveTff7b72=Tff7b72FalseTb4b4b4)
Te6edf3ro Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffroom_orderTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3roTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Te6edf3cleaned Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3r Tff7b72in Te6edf3roTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3rTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3rTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Te6edf3cleanedTff7b72.Td2a8ffappendTb4b4b4(Te6edf3protoTff7b72.Td2a8ffnormalize_roomTb4b4b4(Te6edf3rTb4b4b4)Tb4b4b4)
Te6edf3hubTff7b72.Td2a8ffroom_order Tff7b72= Te6edf3cleaned
Te6edf3ar Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffauto_reconnectTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3arTb4b4b4, Tffa657boolTb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffauto_reconnect Tff7b72= Te6edf3ar
Tff7b72elif Te6edf3ar Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffauto_reconnect Tff7b72= Tff7b72True
Te6edf3al Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffauto_listTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3alTb4b4b4, Tffa657boolTb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffauto_list Tff7b72= Te6edf3al
Te6edf3aw Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffauto_whoTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3awTb4b4b4, Tffa657boolTb4b4b4)Tb4b4b4:
Te6edf3hubTff7b72.Td2a8ffauto_who Tff7b72= Te6edf3aw
Te6edf3no Tff7b72= Te6edf3eTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnickTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3noTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3noTb4b4b4:
Te6edf3hubTff7b72.Td2a8ffnick_override Tff7b72= Te6edf3no
Tff7b72tryTb4b4b4:
Te6edf3hubTff7b72.Td2a8ff_load_historyTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3exTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(
Ta5d6ff"Ta5d6ffFailed to load RRC history for Ta5d6ff" Tff7b72+ Te6edf3hubTff7b72.Td2a8ffname Tff7b72+ Ta5d6ff"Ta5d6ff: Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3exTb4b4b4)Tb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4,
Tb4b4b4)

Tff7b72def Td2a8ffsaveTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_loadingTb4b4b4:
Tff7b72return
Te6edf3path Tff7b72= Tff7b72selfTff7b72.Td2a8ff_store_pathTb4b4b4(Tb4b4b4)
Te6edf3tmp_path Tff7b72= Te6edf3path Tff7b72+ Ta5d6ff"Ta5d6ff.tmpTa5d6ff"
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_save_lockTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3entries Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Tff7b72for Te6edf3h Tff7b72in Tff7b72selfTff7b72.Td2a8ffhubsTb4b4b4:
Te6edf3entriesTff7b72.Td2a8ffappendTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_hub_entryTb4b4b4(Te6edf3hTb4b4b4)Tb4b4b4)
Te6edf3data Tff7b72= Te6edf3protoTff7b72.Td2a8ffencodeTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffhubsTa5d6ff"Tb4b4b4: Te6edf3entriesTb4b4b4}Tb4b4b4)
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffdirnameTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4, Te6edf3exist_okTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3tmp_pathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3fTff7b72.Td2a8ffflushTb4b4b4(Tb4b4b4)
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8fffsyncTb4b4b4(Te6edf3fTff7b72.Td2a8fffilenoTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3osTff7b72.Td2a8ffreplaceTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3pathTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3tmp_pathTb4b4b4)

Tff7b72def Td2a8ff_hub_entryTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hTb4b4b4)Tb4b4b4:
Te6edf3joined Tff7b72= Tffa657setTb4b4b4(Te6edf3hTff7b72.Td2a8ffroomsTb4b4b4)
Te6edf3parted Tff7b72= Tffa657setTb4b4b4(Te6edf3hTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffkeysTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72- Te6edf3joined
Te6edf3entry Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4: Te6edf3hTff7b72.Td2a8ffhub_hashTb4b4b4,
Ta5d6ff"Ta5d6ffdest_nameTa5d6ff"Tb4b4b4: Te6edf3hTff7b72.Td2a8ffdest_nameTb4b4b4,
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Te6edf3hTff7b72.Td2a8ffnameTb4b4b4,
Ta5d6ff"Ta5d6ffroomsTa5d6ff"Tb4b4b4: Tffa657sortedTb4b4b4(Te6edf3joinedTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffparted_roomsTa5d6ff"Tb4b4b4: Tffa657sortedTb4b4b4(Te6edf3partedTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffauto_reconnectTa5d6ff"Tb4b4b4: Tffa657boolTb4b4b4(Te6edf3hTff7b72.Td2a8ffauto_reconnectTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffauto_listTa5d6ff"Tb4b4b4: Tffa657boolTb4b4b4(Te6edf3hTff7b72.Td2a8ffauto_listTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffauto_whoTa5d6ff"Tb4b4b4: Tffa657boolTb4b4b4(Te6edf3hTff7b72.Td2a8ffauto_whoTb4b4b4)Tb4b4b4,
Tb4b4b4}
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3hTff7b72.Td2a8ffnick_overrideTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3hTff7b72.Td2a8ffnick_overrideTb4b4b4:
Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffnickTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3hTff7b72.Td2a8ffnick_override
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3hTff7b72.Td2a8ffcustom_nameTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Te6edf3hTff7b72.Td2a8ffcustom_nameTb4b4b4:
Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffcustom_nameTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3hTff7b72.Td2a8ffcustom_name
Te6edf3icon Tff7b72= Te6edf3hTff7b72.Td2a8ffget_hub_iconTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3iconTb4b4b4:
Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffhub_iconTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3icon
Tff7b72if Te6edf3hTff7b72.Td2a8ffroom_orderTb4b4b4:
Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffroom_orderTa5d6ff"Tb4b4b4] Tff7b72= Tffa657listTb4b4b4(Te6edf3hTff7b72.Td2a8ffroom_orderTb4b4b4)
Tff7b72return Te6edf3entry

Tff7b72def Td2a8ffreorder_hubsTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3hub_hashesTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3hub_hashesTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
Te6edf3order Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3hh Tff7b72in Te6edf3hub_hashesTb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3hhTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3hub Tff7b72= Tff7b72selfTff7b72.Td2a8fffind_hub_by_hexTb4b4b4(Te6edf3hhTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3hub Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3orderTff7b72.Td2a8ffappendTb4b4b4(Te6edf3hubTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3remaining Tff7b72= Tb4b4b4[Te6edf3h Tff7b72for Te6edf3h Tff7b72in Tff7b72selfTff7b72.Td2a8ffhubs Tff7b72if Te6edf3h Tff7b72not Tff7b72in Te6edf3orderTb4b4b4]
Tff7b72selfTff7b72.Td2a8ffhubs Tff7b72= Te6edf3order Tff7b72+ Te6edf3remaining
Tff7b72selfTff7b72.Td2a8ffsaveTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_notify_changeTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72True

Tff7b72def Td2a8ffto_dictTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Return a JSON-serializable summary of all configured hubs."""
Tff7b72with Tff7b72selfTff7b72.Td2a8ff_lockTb4b4b4:
Te6edf3hubs Tff7b72= Tffa657listTb4b4b4(Tff7b72selfTff7b72.Td2a8ffhubsTb4b4b4)
Tff7b72return Tb4b4b4{Ta5d6ff"Ta5d6ffhubsTa5d6ff"Tb4b4b4: Tb4b4b4[Te6edf3hTff7b72.Td2a8ffto_dictTb4b4b4(Tb4b4b4) Tff7b72for Te6edf3h Tff7b72in Te6edf3hubsTb4b4b4]Tb4b4b4}

Tff7b72def Td2a8ffshutdownTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3h Tff7b72in Tffa657listTb4b4b4(Tff7b72selfTff7b72.Td2a8ffhubsTb4b4b4)Tb4b4b4:
Tff7b72with Te6edf3contextlibTff7b72.Td2a8ffsuppressTb4b4b4(Tf85149ExceptionTb4b4b4)Tb4b4b4:
Te6edf3hTff7b72.Td2a8ffdisconnectTb4b4b4(Tb4b4b4)


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────